Quest Documentation Index

Quest 3.12 Documentation

Using Quest

Quest is a system for playing and creating text adventure games.

Playing Games with Quest

ASL Reference
Full reference guide to the powerful ASL language that Quest uses.

QDK User's Guide
Information on making games using the visual editor QDK.

The Good Text Guide
You can't just "knock up" an amazing game - it takes effort. This guide contains some simple advice on avoiding common oversights to make your game more enjoyable.

Quest Pro

Upgrade to Quest Pro!
Details on purchasing Quest Pro and its benefits, such as being able to hide the code behind your games.

QCompile Manual

Information

Contact Axe Software

File Information
Details on each of the files in your Quest directory and what they do.

Quest Documentation Version v3.12; last updated 3rd December 2002. All documentation copyright © 1998-2002 Axe Software. Quest logo by Ray Pang.


Playing Games with Quest

You can play single-player games on your own system, or connect to a QuestNet server to play multiplayer games over a network or the internet.

Playing Single-Player Games

Playing Multi-Player Games

Types of File


Single Player Games

Playing Single-Player Games With Quest

To play a game with Quest, you can double-click on a Quest game or saved game from Windows Explorer, or you can start Quest from your Start menu.

You can download games for Quest from the Quest Games Archive.

The first time you run Quest, you will have no "favourite games" in the list and no saved games, so you should click the "Load a game" button. If you have downloaded a game from the games archive, find it on your hard disk and click the "Open" button. You will be returned to the Quest Start window. At this point, you might want to add the file you just selected to the Favourites list, by clicking the "Add to Favourites" button. This will make the game easier to access next time you start Quest.

Start the game by clicking the "Play" button.

Once you've loaded a game, you will be presented with the main Quest window. You can navigate around and interact with the game using the arrow buttons and the "Places and Objects" box. You can also type commands in at the bottom of the window - click the "Help" button or type HELP and press Enter for details on the kinds of commands you might be able to use in a game.


Multiplayer Games

Playing Multi-Player Network Games With Quest

Quest lets you connect to a QuestNet server to play multi-player adventure games over a network or the internet.

To play a game on a QuestNet server, you first need to know the host address and port number of a server you wish to connect to. Details of QuestNet servers that are usually available will be posted to the Axe Software website - at the current time your best bet is, however, a server you are running yourself. If you want to run your own QuestNet server, you can download the latest version of QuestNet Server from the QuestNet page on the Axe Software Quest website.

To connect to a QuestNet server, select the "Network" tab on the Quest Start window. Enter your name (or nickname), and the host address. The port number will usually be 10001. You can now add this server to a list of "favourite" servers by clicking on the "Add to list" button, or you can connect immediately by clicking "Connect".

If you connect successfully, you should see a pop-up welcome message and text should appear in the main Quest window.

You can now navigate around the adventure game world in the same way as you would for a normal Quest game.

To speak to other players:

  • to say something to everybody in the current room, type: say followed by what you want to say. For example, to say "this is fun" to everybody in the room, type say this is fun.
  • to say something to a particular person in the current room, type to followed by the player's name and a comma, then what you want to say. For example, to say "hello there!" to the player called "alex", type to alex, hello there!. Alternatively, a simpler method is to select the player from your objects list and click "Speak to", and then type what you want to say.

To disconnect, Click "Quest", then "Exit this game".


File Types

Quest File Types

ASL (Adventure Scripting Language)
This is the format that games are created in. Games you create yourself should be saved with an extension of ".asl".
CAS (Compiled ASL)
This is the "compiled" version of the ASL, which will hide the code of your game from anybody who looks at the file, making it very difficult to cheat by looking inside it. ASL files can be converted to CAS files by using the QCompile utility that is included with the Quest Pro. For information on Quest Pro, click here.
QSG (Quest Saved Game files)
These are files saved to your hard disk when you play games and save them, in order to finish them some other time.


ASL Reference

ASL Programmer's Reference for Quest

The contents of this document apply to ASL version 311, as used in Quest 3.11 and later.

Introduction
An introduction to the basics of ASL coding

Definition Blocks
Full reference for all definition blocks that can exist in a game

Script Commands
A-Z reference to all script commands

Built-in Functions
Functions for object handling, string handling, and more

Built-in String Variables
Variables for room descriptions and player input

Quest Methods
Guides to using object properties and actions, libraries and arrays

How To...
...use other Quest features

Important Notes for Users of Previous Versions


ASL Reference: Introduction

This document details the syntax and use of ASL 311, the scripting language used in Quest 3.11 and later. Please note that as it is intended for use as a reference to ASL (Adventure Scripting Language) and not as a tutorial, some features may not be relevant to beginner ASL coders - so don't worry if you don't understand everything when you first read it!

If you used a previous version of Quest, please see the Notes for Users of Previous Versions. For full information, including bug fixes, please read VERSIONS.TXT in your Quest directory.

Creating and Editing a Game

The Components of an ASL File: Definition Blocks

How Syntax is Formatted in this Document

ASL Definitions

A Note About Typing in Script Commands

About Parameters

About Braces


Creating and Editing a Game

The easiest way to create your own games for Quest is to use the included QDK utility. QDK allows for easy visual editing of Quest games. For full information on QDK, please read the QDK User's Guide.

This ASL reference guide contains all the information you need for creating powerful games easily "by hand" using any text editor such as TextPad (recommended) or Notepad. It will also help you if you just want to be able to tweak the code that QDK produces.

If you want to create games using a text editor, the easiest way to do it is to edit the included TEMPLATE.ASL and fill in the blank spaces, and then add code as required.

TIP: Editing the Template file

The template file can be edited in any text editor, such as Notepad. To open the TEMPLATE.ASL file, open your text editor, then select File|Open. In the "Files of type" box, select "All files (*.*)". Then find the TEMPLATE.ASL file and open it.

When saving, click File|Save and enter a new name for your game. Give it a .asl extension and surround the file name in quotes. For example, you might want to enter mygame.asl, including in the quotes, in the "File name" box. By including the quotes, you stop your text editor adding the .txt extension.

If you do save with a .txt extension, run Quest and click "Load a game". Find the directory you saved your file in, then, in the "Files of type" box, you need to select "Text files (*.txt)". Your file will then be shown in the list of files.


About Definition Blocks

The Components of an ASL File: Definition Blocks

All ASL files consist of a number of "blocks" of definitions - one block, called the "define game block" or "game definition block", defines general properties of a game. The game definition block begins with a line starting with "define game" and ends, like all definition blocks, with "end define". Other blocks define the locations that exist in a game - room definition blocks. Within these blocks, further blocks may exist that define objects - what they look like, and how they behave.

More advanced blocks - procedures and functions - consist of a series of script commands, which tell Quest to do something. Other blocks define equivalent words (synonyms) and menus.

The ASL Reference is divided up into sections dealing with each kind of block that may exist in a game's ASL file.


Syntax Formatting

Throughout this document I've used syntax formatting in order to show how the various commands should be used. Please be aware that syntax formatting often shows a lot of brackets which you do not need to type - in fact, typing the brackets will stop Quest from working properly.

[…] = optional item (do not type the brackets)

{ this | that } = "this" or "that" must be entered here (again, do not type the brackets)

(thing) = any type of "thing" - for example, (script) means any script command, (object) means any object. Once more, do not type the brackets.

For example, if [not] is <(string); (string)> then (script) [else (script)] means:

The "if" part must be present
The "not" part is optional
The "is" part must be present
The "<" part must be present
A string must be present
The semicolon must be present
A string must be present
The ">" part must be present
The "then" part must be present
Any script command must be entered after "then"
Optionally, an "else" followed by any script command can be present.

An example of a statement of the above form is:

if is <mynumber; 7> then msg <My number is seven.>

And another example is:

if not is <mystring; potato> then msg <You idiot!> else msg <You weirdo!>


ASL Definitions

In alphabetical order:

Function: Similar to a procedure, but returns a value or string when finished. You can call a function from inside any parameter by enclosing the function name in "$" characters.

Object: Objects are fundamental to the way Quest works. Objects live in rooms or a player's inventory, and can be moved around, talked to, used on or given to other objects, and more.

Parameter: A parameter is some information that you give to Quest's built-in functions or a function of your own making. Parameters for Quest's built-in functions are usually given between "<" and ">" characters and are separated (if there is more than one parameter) by semicolons. For example, <string; number> is a parameter with two "arguments". Parameters for functions that you make yourself are given in the same way, but between normal brackets () rather than pointy brackets <>, as these functions are themselves part of parameters for something else.

Procedure: A sequence of script commands, which can be called from anywhere within a game.

Room: A place in a game. It could be a room in a building, or it could be a place or part of a place such as a street or shop front - essentially any location you want in a Quest game needs to be set up as a "room".

Script: A command that tells Quest to do something - print a message, move an object, finish the game, play a sound, etc.

String: A word, sentence, or other sequence of letters. These are used in Quest to contain information about user-defined commands, location, etc., and can be used for other things such as objects that can be "written" on by the player, for example.

Tag: A particular property of an object, room etc. that defines how it works and behaves. An object may have a "take" tag, for example, that defines what happens when the object is taken.

Variable: A value or string that can be changed - think of it as a "box". A variable can contain either a string (a string variable) or a number (a numeric variable). The contents of the "box" can be read or changed at any time. You can access the contents of a string variable within any parameter by enclosing the variable name with "#" characters, and similiarly a numeric variable can be accessed inside any parameter by enclosing its name with "%" characters.


A Note About Typing in Script Commands

Script commands, such as msg <Hello, world!> must:

  • be entirely in lower case
  • have a space between the command (eg, msg) and the parameter (eg, <Hello, world!>)

Parameters must have a "<" in front and a ">" at the end.

So, these forms are incorrect:

MSG <Hello, world!>
msg<Hello, world!>
MSG<Hello, world!>
Msg <Hello, world!>
msg <Hello, world!

This form is the only correct form:

msg <Hello, world!>

Leading spaces and tabs are insignificant, and are ignored by Quest.


About Parameters

Parameters are whatever appears between "<" and ">" characters - after an msg command, give command, etc.

A parameter could be completely static - always returning the same string. Indeed, some parameters must always be static - the parameter for the start room, for example, might be something like "<house>". This parameter always gives Quest the text "house".

However, for flexibility, you can make parameters return different things when it makes sense to do so by making them include the contents of variables or the output of functions. You include the contents or output from a variable or function by surrounding the variable or function name with special characters: "#" denotes a string variable; "%" a numeric variable and "$" a function.

For example, a parameter for a msg script command, which prints a message, could contain the contents of a string variable "playername", which holds the player's name. You could use:

msg <Your name is #playername#>

If the string variable "playername" contained the name "Alex", this parameter would then return the text "Your name is Alex", which would then be printed on the screen by the msg command.


About Braces

Some tags take script commands - for example, the speak tag in an object definition can take a script command to execute when the player speaks to that object, for example:

speak say <"La la la I'm not listening to you!">

If you want to specify more than one line of script to execute, surround the script commands in braces { }.

For example, you might want the object, when spoken to, to steal the player's handbag and say nasty things to them (or something):

define object <Nasty youth>
    speak {
        hide <handbag>
        say <You smell!> }
end define

Braces can also be used to create complex if statements:

if got <handkerchief> then {
    say <I'll have that, mate!>
    hide <handkerchief>
    msg <The thug steals your hanky!> }
else {
    say <What, no hanky?>
    msg <He kicks you where it hurts.>
    hide <testicles> }

Note that with if statements, the else can appear on the following line whether braces have been used or not. For example:

if got <potatoes> then msg <I see you have potatoes!>
else msg <You appear to be agriculturally lacking.>


Definition Blocks

There follows information on all types of definition blocks that may appear in ASL file, and what may be contained within them.

This means our first section doesn't strictly belong here, but there really is no better place to put it:

Script Commands Which May Be Anywhere

Basic definition blocks

Game Definition Block
- Status Variables

Rooms

Objects

Procedures/Functions

Text Blocks

More specialised definition blocks

Menus

Synonyms

Timers

Type Definition Blocks


Script Commands Which May Be Anywhere

Most script commands need to appear inside a definition block of some kind. The script commands below, however, may feature either inside a definition block, or outside a definition block (usually at the beginning of an ASL file).

!include <(library name)>

Includes the specified library in this game.

- see also Using Libraries

' (comment)

Comment. These lines will be ignored by Quest, and can appear inside or outside "define" blocks. You could use comments to write reminders to yourself, eg:

' To do: Dungeon room, ending text

Or you could use it to temporarily remove a line, or several lines, of script, without having to delete and retype it - just put an apostrophe ' at the beginning of the lines you temporarily want Quest to ignore.

You can also place a comment after any line of Quest code - Quest will ignore everything after an apostrophe that isn't within a parameter. For example:

msg <It's a lovely day.>  ' Prints a lovely description


Game Definition Block

The Game Definition Block

All ASL files must have one, and only one, game definition block. The first line of the game definition block must be:

define game <(game name)>

where the name of the game must be entered between the < and the >, e.g.:

define game <Billy's Quest for the Holy Egg>

An example of a full game definition block might be:

define game <Thumper Mission>
    asl-version <311>
    start <field>
    command <eat cabbage> do <eat-procedure>
    game version <1.0>
    game author <Peter Rabbit>
    game copyright <© 2002 Peter Rabbit Enterprises>

    define variable <cabbages>
        value <5>
        display <You have ! cabbages>
    end define
end define

The following lines may appear in a game definition block:

action <(action name)> (script)

Sets up the action specified. Many of these tags may exist within one game definition block. See the object action tag for more details. For the purposes of executing these actions, use the object name "game".

- see also action and doaction script commands, type tag, type definition blocks

afterturn (script)

Executes the specified script every turn, after what the player typed has been evaluated.

- see also beforeturn

asl-version <(version number)>

ASL version number. If this number is higher than the ASL version number that the current version of Quest knows it can cope with, a warning message will be shown (and will be output to the file specified in Quest's Options window, under "Log ASL script messages to a file:"). The game will still load and run, however.
- usually asl-version <311>

background <(colour)>

Specifies the background colour. Valid values for the colour are white, black, red, green, yellow, blue. Players may override this by forcing a game to use Windows default colours, so don't rely on this tag always working.

- see also foreground tag, foreground, background script commands, How to Format Text

beforeturn (script)

Executes the specified script right after the player types in a command – before it is evaluated (i.e. as soon as the player hits the Enter key).

- see also afterturn

command <(command string) [; (command string) ... ] > (script)

Executes the specified script when the user-defined command is typed in during the game. Multiple commands can be catered for with the same script by separating them with semi-colons. See How to Add Your Own Commands to a Game for complete information.

e.g.:

command <read #object#> exec <look at #object#>

- see How to Add Your Own Commands to a Game for full information

default fontname <(name of font)>

Sets the default font used in the game. This overrides any default font name specified by the player in Quest's options window, though the player can in turn override your attempts to set the default font by selecting the option to override game-set default fonts.

- see also default fontsize, font script command, How to Format Text

default fontsize <(font size)>

As above for "default fontname", but sets the default font size.

- see also default fontname, font script command, How to Format Text

description { (script) | <(description text)> }

Overrides Quest's room descriptions by executing the script you specify here, or writing the text you specify here, rather than print Quest's default room description.

- see also How to Customise Room Descriptions

error <(error name); (error message string)>

Overrides Quest's built-in messages. Some of them are not actually error messages, but default messages for things that frequently happen.

This table shows the valid "error name" strings, and the circumstances in which that message is printed:

Error name | Printed when...
badcommand | the player types an invalid command
baddrop | the player tries to drop an object they are not carrying
badexamine | the player uses "examine" in an unrecognized way
baditem | the player tries to take an object which does not exist
badgo | the player uses "go" in an unrecognized way
badgive | the player uses "give" and does not specify an object to give to
badlook | (obsolete from Quest 3.1 onwards)
badplace | the player tries to go to a non-existent room using "go to ...".
badpronoun | the player uses a pronoun ("IT" etc.) when that pronoun doesn't refer to anything (the pronoun used is returned in #quest.error.pronoun#)
badtake | the player tries to take an object which can't be picked up
badthing | the player tries to do something to an object that does not exist
baduse | the player uses "use" in an unrecognized way
cantdrop | the player tries to drop an object that can't be dropped
defaultdrop | the player successfully drops an object (the article (e.g. "it", "them") is returned in #quest.error.article#)
defaultexamine | the player examines something for which there is no examine tag defined
defaultlook | the player looks at something for which there is no "look" tag defined
defaultout | the player tries to use "out" to exit from a room which has no "out" tag
defaultspeak | the player speaks to an object for whom there is no "speak" tag defined
defaulttake | the player picks up an object successfully. e.g. "You pick it up."
defaultuse | the player tries to use something on an object where no relevant "use" tag can be found
itemunwanted | an object does not want an object being given to it (i.e., no relevant "give" tag can be found)
noitem | the player tries to use an object they don't have

For example:

    error <noitem; You don't appear to have that, you silly person!>
    error <defaultdrop; You have successfully dropped #quest.error.article#.>

foreground <(colour)>

Specifies the foreground colour. Valid values for the colour are white, black, red, green, yellow, blue. Players may override this by forcing a game to use Windows default colours, so don't rely on this tag always working.

- see also background tag, foreground, background script commands, How to Format Text

game { author | copyright | version | info } <(string)>

Provides a space for you to give information about the game - who wrote it, copyright details, version number and other information. These can be called up by the player by using the ABOUT command on the main window, or by selecting the "Help|About This Game" menu.

nodebug

Turns off the "debug" windows for this game - the "Debug" menu is hidden. This is useful for released games where you don't want players peeking into what's going on - particularly useful for compiled games where this statement can't be removed by the player.

properties <(property or property list)>

Sets properties for this game. You can specify multiple properties separated by semicolons. See the object properties tag for more details. For the purposes of reading these properties, use the object name "game".

- see also type, type definition blocks, property script command

start <(room)>

Specifies the start room. e.g.:

start <Billy's House>

startscript (script)

All script specified here will be executed when the game starts, before the start room has been entered. You can use this section to play an intro sequence, for example. If the script you specify here contains a "nointro" line, the introductory text (as specified by "define text <intro>") will not be displayed. You may want to do this if, for example, you are displaying the introductory text manually (using "displaytext <intro>") at some point during the intro sequence.

type <(type name)>

Includes the properties and actions in the specified type definition block.

- see also properties, action

use <(object)> (script)

Executes the specified script when the object specified is used at any point in the game. The player must have the object for the script to be executed. For example:

use <destroy spell> do <destroy-procedure>

will execute the procedure "destroy-procedure" whenever the player types "USE DESTROY SPELL", providing the player has the object "destroy spell" in his/her inventory. If the player does not have the "destroy spell" object in his/her inventory, the noitem error message is printed (or a default error message is displayed).


Status Variables

Status Variable Definition Blocks

Status variable definition blocks replace the "collectables" that could be used in Quest 2.x. A status variable acts in exactly the same way as an ordinary numeric or string variable, except that its value is always displayed in a status area on the Quest window, underneath the inventory. Examples of variables you might set up as status variables are health and money - so the player can always check how healthy they are, how much money they have etc. by glancing to the right-hand side of the Quest window.

Status variable definition blocks may appear only within the game definition block.

An example of a status variable definition block is:

define variable <health>
    type numeric
    value <100>
    display <!%% health>
    onchange if (%health% <= 0) then playerlose
end define

Here is an explanation of the lines that can appear in a status variable definition block:

display [nozero] <(display string)>

Specifies how Quest is to display the status information for this variable. Use an "!" where you want the value of the variable to be printed, and use "*" characters to surround anything that should only appear in plural forms - for example, "You have ! piece*s* of toast". This will print "You have 1 piece of toast", "You have 2 pieces of toast", etc. Anything between the "*" characters is not displayed when the value of the variable is 1.

Use the nozero parameter if you don't want a numeric variable displayed when its value is zero.

The example above includes two "%" characters in the display tag because Quest uses the "%" character to denote a numeric variable - two "%" characters in the display string will print one "%" character rather than cause an error.

onchange (script)

Optional. If specified, the script will be executed each time the value of the variable is changed. In the above example, this checks whether the health has dropped to zero or below, and if so makes the player lose the game.

type [numeric | string]

Specifies the type of variable. The default is a numeric variable.

value <{ (number) | (string) }>

Specifies the initial value of the variable.


Rooms

Room Definition Blocks

A room definition block defines a room. This may contain one or more object definition blocks within it.

A room definition block starts with the line:

define room <(room name)>

and ends with the line:

end define

A room definition block may contain the following lines:

action <(action name)> (script)

Sets up the action specified. Many of these tags may exist within one room definition block. See the object action tag for more details.

- see also action and doaction script commands, type tag, type definition blocks

alias <(name)>

Defines an alternative name for a room. Use this for place names like "the street" which may appear more than once in a game. Give each place a unique name like "street1" but with an alias of "the street".

afterturn [override] (script)

Executes the specified script every turn that the player is in this room, after what the player typed has been evaluated. If override is specified, any afterturn script in the game definition block will not be executed.

- see also beforeturn

beforeturn [override] (script)

Executes the specified script right after the player types in a command – in this room; before it is evaluated (i.e. as soon as the player hits the Enter key). If override is specified, any beforeturn script in the game definition block will not be executed.

- see also afterturn

command <(command string)> (script)

Executes the specified script when the user-defined command is typed in while the player is in this room. Multiple commands can be catered for with the same script by separating them with semi-colons. See How to Add Your Own Commands to a Game for complete information.

command <read #object#> exec <look at #object#>

- see How to Add Your Own Commands to a Game for full information

description { (script) | <(description text)> }

As for "description" in the "define game" block, this overrides Quest's own room description printing with code or a message you specify. This will apply to the particular room rather than the entire game, however.

As an alternative to automatic room descriptions, you can adopt a more "classical" adventure game style by using the "description" tag in place of a "look" tag in your rooms. If you do this, the only text a player will see when they enter the room will be the description you specify, rather than a full list of all objects in the room and available directions.

For example:

description do <autodescription-procedure>

or

description <You are standing in a freezing alleyway. You can hear a voice in the _
    distance behind you. You can travel north or south.>

- see also How to Customise Room Descriptions, indescription, look

east

see north

indescription <(text to put in description)>

The default "You are in ..." for room descriptions is over-ridden when this tag appears in a room definition. For example, "indescription <You are standing on:>" in a "define room <platform>" will make Quest display "You are standing on a platform" in the room description (if the room has a prefix of "a"). The colon (":") makes Quest return the room name; if you do not include the colon, the room name is not printed (the above would display "You are standing on" on its own). For example, in a room called "top of tower block", you might use:

indescription <You are looking down on the busy road several hundred feet below.>

look <(room description)>

Enter this room's description in this line. E.g.:

look <A very big, impressive concert hall, full of people.>

- see also description

{north|south|east|west|northeast|northwest|southeast|southwest} {<(room)>|(script)}

These specify what happens when the player travels in a given direction - they will either go to a specified room, or some specified script will execute - if script is specified, the player will not automatically be moved anywhere.

Examples:

north <garage>

west {
    if got <key> then {
        msg <You unlock the door and step into the hallway.>
        goto <hallway> }
    else msg <The door is locked.>
}

- see also place and out

northeast

see north

northwest

see north

out <[prefix;] (room)> [(script)]

Specifies what happens when the player types "exit" or "out". As for place, if some script is specified here, the player will not go to the specified room automatically. If a prefix is specified, that is printed in the "You can go out to ..." line in the room description, unless the room specified has an alias (in which case that alias is printed instead).

Examples:

out <the; street>

out <the; corridor> {
    if ( %strength% < 20 ) then msg <You are too feeble to try to force your way past the guard.>
    else goto <corridor> }

The first example adds the line "You can go out to the street" to the room description, and when the player types OUT or clicks the "out" button, they go to the room with the name "street" - the word "the" is the prefix for the description.

The second example executes some script which lets the player go out to the room "corridor" only if they have sufficient strength.

- see also north and place

place <[prefix;] (place name)> [(script)]

Specifies a possible place that the player can go to from this room, by typing "GO TO ...".

An optional prefix can be specified, followed by a semi-colon. For example, an accessible place could be called "supermarket", but this would display the rather unlovely "You can go to supermarket" in the room description - by using "place <the; supermarket>", "You can go to the supermarket" would be displayed, which looks nicer. The player is able to type either "GO TO SUPERMARKET" or "GO TO THE SUPERMARKET" to access this place in any case. Other prefixes you might want to use could be "the local", "your", etc. These make the text displayed to the player much more natural and readable.

If a script is not specified, the destination room must exist, and the player will automatically go to that room when they use this exit. Quest will use the destination room's alias name if it exists.

If a script is specified, the player will not automatically go to the place specified, and indeed, the room name referred to doesn't have to exist at all. Use the goto command to move the player if necessary. You can use this facility to implement things such as locked doors.

You can use the fact that a room doesn't have to exist if you use a script to make a custom name for an exit. If the room you want to exit to is called room004, with an alias of torture chamber, but you want the exit to appear as an exit to the kitchen, then:

place <the; room004>

will display "You can go to the torture chamber". Not very good for a trap! Even though no kitchen room exists, you can use:

place <the; kitchen> goto <room004>

This will display "You can go to the kitchen", and the player can type GO TO KITCHEN, but they will end up in the torture chamber instead.

- see also north and out

prefix <(prefix)>

Defines the prefix for this room, e.g. "the". This prefix is used in the room description and is printed before the name of the room.

properties <(property or property list)>

Sets properties for this room. You can specify multiple properties separated by semicolons. See the object properties tag for more details.

- see also type, type definition blocks, property script command

south

see north

southeast

see north

southwest

see north

script (script)

Executes the specified script when the person enters the room. Could be used for a nasty trap, for example, or to play a sound or to show a picture.

type <(type name)>

Includes the properties and actions in the specified type definition block.

- see also properties, action

west

see north

use <(object)> (script)

Executes the specified script when the object specified is used in this room. The player must have the object for the script to be executed.


Objects

Object Definition Blocks

An object definition block defines how an object appears and how it behaves. The object definition block usually appears within a room definition block - usually the room that the object first appears in. However, it can also appear in the game definition block, or it can "float" outside any other block. Such objects won't appear anywhere until they're moved. You may find this useful if you have a particular object that only ever appears in the player's inventory, for example (although in that case you may as well put it directly in the inventory room, which is the player's inventory, and make it hidden).

An object definition block starts with the line:

define object <(object name)>

and ends with the line:

end define

Note that you should not begin an object's name with "the" - i.e., don't call an object "the sign"; instead call it "sign" and give it a prefix of "the" (see below). The following lines may appear within an object definition block:

action <(action name)> (script)

Sets up the action specified. Many of these tags may exist within one object definition block.

For example, you could give an object an "eat" action such as:

action <eat> do <object-eat-procedure(banana)>

As with properties, the action specified here will override any action with the same name included by using a type tag.

- see also action and doaction script commands, type tag, type definition blocks

alias <(name)>

Specifies the name of this object that is presented to the player. All objects must have unique names, so if you want to have two objects called "book", give them different "real" names (say, "book1" and "book2") and then give them both an alias of "book". In case both books appear in the same place and Quest is unable to distinguish between the two, a menu appears asking the player to select which object they mean. The description for the object on this menu is provided by the optional detail tag. You can specify additional names that the player might use to refer to this object using the alt tag.

- see also alt

alt <(alternative names; ...)>

Here you can specify other names that a player can use to refer to this object. Separate multiple names with semicolons. Objects can share "alt" names just as they can share aliases, and in the case of ambiguity, the standard disambiguation menu appears. See The Good Text Guide for an example of a case where's it's a good idea to make use of the alt tag.

- see also alias

article <(article)>

Specifies the article for this object, usually either "it" or "them". The default is "it". This is used in player error messages such as "You can't drop it."

detail <(description)>

A short description of the object used in case of ambiguity where two objects share the same alias. This is the description that appears on the disambiguation menu, so keep it short and distinct from other detail tags. You only need to use this tag if there is another object in the game sharing this object's alias, and then only if there is a possiblity that both objects will end up in the player's inventory or in the same room.

displaytype <(display type name)>

Specifies what "type" to display this object as in Quest's "Places and Objects" list. Quest 2.x had separate "character"s and "object"s for animate and inanimate objects respectively, so you can emulate this (and stop objects representing people from having a displayed type name of "object") by setting this tag to something like "person" or "animal" etc.

drop ...

There are two forms of the drop tag:

drop { everywhere | nowhere } [<(message)>]

Prints the specified message, if any, when the player tries to drop the object. If "everywhere" is specified, the object is automatically dropped. If "nowhere" is specified, the object cannot be dropped.

drop (script)

Executes the specified script when the player tries to drop the object.

If no drop tag is specified, the object can by default be dropped anywhere, and the message specified by the defaultdrop error in the game definition block is printed, or a default message.

examine {<description>|(script)}

Like look, except this specifes what happens when the object is examined. If not specified, the look tag text or script is used.

- see look

gain (script)

Specifies a script to execute when this object is gained by the player. This only works for the standard "giving" of an object to the player, and not when the object is manually moved into the "inventory" room.

- see also lose tag, give script command

give ...

There are four forms of the give tag. When the player types something of the form GIVE A TO B, your game can handle it in the following ways:

give <(object A)> (script)

(in the object B definition) Specifies the script executed when the specified object A is given to this object. For example, give <potato> say <Cheers mate!> will say "Cheers mate!" when the player gives the potato to the object.

give to <(object B)> (script)

(in the object A definition) Specifies the script executed when this object is given to the specified object B.

give anything (script)

(in the object A definition) Specifies the script executed when any object is given to this object.

give to anything (script)

(in the object B definition) Specifies the script executed when this object is give to any object.

For give anything ... and give to anything ..., the game can find out what the other object is by reading the #quest.give.object.name# string variable. This will return the real (unaliased) name of the object.

The priority for give tags is the order in which they appear above. If no suitable give tag can be found for GIVE A TO B, the defaultgive error in the "define game" block will be printed, or a default message will be printed if none is specified.

- see also use

gender <(gender)>

Specifies what gender this object is referred to as - use "he", "she" or "it". This tag should be specified in lower case unless any of the letters are always in upper-case. If omitted, "it" is used.

hidden

Specifies that the object is, by default, not displayed "in" the room when the game starts and is inaccessible to the player - to all intents and purposes, it does not exist. To make it appear and "exist", the script command show must be executed. This tag is useful for objects which appear in rooms later on in the game, as the plot develops.

- see also invisible, show script command, hide script command

invisible

Specifies that the object exists in the room and can be interacted with, etc., but does not appear in either the room description or the objects list.

- see also hidden, reveal / conceal script commands

look {<description>|(script)}

Specifies what happens when the object is looked at. It can either be a line of script (for example do <look_at_bloke_procedure>) or it could simply be a line of text for a description. E.g.:

look <He's an ugly-looking thug.>
look do <turn_to_stone>

- see also examine

lose (script)

Specifies a script to execute when this object is lost by the player. This only works for the standard "losing" or dropping of an object, and not when the object is manually moved from or hidden from the "inventory" room.

- see also give tag, lose script command

prefix <(prefix)>

Specifies whether the object is referred to as "a (name)", "the (name)" or just "(name)", etc. For example, an object "shop assistant" would perhaps have a prefix of "a". An object "Cyclops" would probably have a prefix of "the", whereas "Mr. Smith" wouldn’t have a prefix. Prefixes should be specified in lower case. e.g. prefix <the>, except in cases where they are always displayed with capitals.

- see also suffix

properties <(property or property list)>

Sets what properties this object has. You can specify multiple properties separated by semicolons. The format for properties is:

[not] property name [= { (value) | (string) }]

For example:

properties <wearable; hunger=12; type=animal>

The inclusion of not will cancel that property if inherited by using a type tag. For example, if type <food> included a property "edible", using properties <not edible> would mean that this object would not have the "edible" property, but would still inherit the rest of the "food" type properties.

Object properties can be read from script:

  • See Reading Properties and $objectproperty(...)$ function for properties with a value
  • See if property for properties without a value

- see also type, type definition blocks, property script command

speak {<speak text>|(script)}

Specifies what the object does when spoken to. It can either be a line of script (for example do <proc-blokespeak>) or it could simply be a line of text that the object says in reply. E.g.:

speak <Hello there. Lovely weather we're having>
speak do <proc-hitoverheadwithamallet>

suffix <(suffix)>

Specifies text to display after the object name in the room description. For example, if you wanted the description of the room to show that there was "a scary monster with large teeth" in the room, you would use a prefix of "a scary", an object name of "monster" and a suffix of "with large teeth".

- see also prefix

take [(script)]

Specifies that the object can be taken. If no script is specified, the object is moved from the current room to the player's inventory. If a script is specified, it is executed and the object is not automatically moved to the player's inventory.

type <(type name)>

Includes the properties and actions in the specified type definition block.

- see also properties, action, type script command

use ...

There are five forms of the use tag. The first form is used for when a player types something of the form USE OBJECT:

use (script)

Specifies what script to execute when a player types USE followed by the object name, without specifying another object to use it on. Note that any use <object> (script) in a room definition block will take priority if the object is used in that room.

When the player types something of the form USE A ON B, your game can handle it in the following ways:

use <(object A)> (script)

(in the object B definition) Specifies the script executed when the specified object A is used on this object. For example, use <hammer> say <Owch!> will say "Owch!" when the player uses the hammer on the object.

use on <(object B)> (script)

(in the object A definition) Specifies the script executed when this object is used on the specified object B.

use anything (script)

(in the object A definition) Specifies the script executed when any object is used on this object.

use on anything (script)

(in the object B definition) Specifies the script executed when this object is used on any object.

For use anything ... and use on anything ..., the game can find out what the other object is by reading the #quest.use.object.name# string variable. This will return the real (unaliased) name of the object.

The priority for use tags is the order in which they appear above. If no suitable use tag can be found for USE A ON B, the message defined by any error <defaultuse; (message)> in the " define game" block will be printed, or a default message will be printed if none is specified.

- see also give


Procedures and Functions

Procedure and Function Blocks

These define a procedure or function, which is a set of one or more lines of script.

define procedure <procedurename>
    .
    .
end define

and

define function <functionname>
    .
    .
end define

A procedure can be called anywhere using the do script command.

Calling a function is almost exactly the same as calling a variable - you just put the function name inside "$" signs within a parameter. For example, the following would return whatever value was output by the function "myfunction":

msg <MyFunction returned $myfunction$.>

A function returns a value using the return command somewhere within the function definition block:

return <(value)>

You can pass parameters to functions and procedures by enclosing them within brackets after the function or procedure name and separating them (if there are more than one) with semicolons. For example, to pass parameters of "3", "potato" and "sausage" to a function named myfunction, you'd call it in a parameter containing:

$myfunction(3;potato;sausage)$

To pass these same parameters to a procedure called myprocedure, use the script command:

do <myprocedure(3;potato;sausage)>

To see what parameters a function or procedure has been passed, see the Parameter Functions section.

- see the script commands section for script commands that can be included in a procedure or function.


Text Blocks

Text blocks are used for large chunks of text that may need to be reused, or may be awkward to display with commands like msg because of their size.

By default, a text section named "intro" is displayed at the start of the game (unless nointro is specified in the startscript tag of the "define game" block); a text section named "win" is displayed when the player wins the game (i.e. playerwin is called) and a text section named "lose" is displayed when the player loses (i.e. when playerlose is called).

You can also make text sections by other names, and display them at any time using the displaytext command.

A text section is of the following format:

define text <(text section name)>
Text to display...
    .
    .
    .
end define

Note that text sections do not convert strings - if the text section contains "#mystring#", "#mystring#" will be printed, rather than the contents of the mystring string variable.


Menus

Selection Definition Blocks

A selection definition block defines a menu of choices. You can call up a menu by using the choose script command. Selection definition blocks are special in that they act as "doorways" to other procedures or script commands - the player chooses the script which is executed. When they are called, a window pops up with a list of choices and the player is able to choose one by selecting one and then clicking "Select". A selection definition block looks like this:

define selection <selectionname>
    info <Information about the menu>
    choice <A choice> (script)
        .
        .
        .
end define

Only one "info" line may be present. Each "choice" line corresponds to a different selection on the menu, and you can have as many "choice" lines in any selection definition block as you like.

choice <(selection text)> (script)

This specifies the text displayed for each choice, and the script executed when it is selected.

info <(information text)>

Specifies the text displayed when the user is prompted to make a choice from this menu.


Synonyms

The Synonyms Definition Block

There can only be one synonyms definition block in a game, if any. It defines the synonyms in use - that is, words that Quest will accept as meaning the same thing. These are useful for user-defined commands - you only need to specify one form, and then you can use synonyms to cater for other ways of saying the same thing. For example, you could specify a user-defined command "write", and then have synonyms of "scribble", "etch", "draw" all equating to "write". Whenever the player types "scribble", "etch" or "draw", Quest will internally replace it with "write".

To set up the above example, you'd use:

define synonyms
    scribble; etch; draw = write
end define

The syntax format for lines in the synonyms block is:

(synonym1) [; (synonym2); (synonym3); …] = (word)


Timers

Timer Definition Blocks

Timers allow you to run a certain script at regular time intervals. You could use this to add a real-time element to your game.

Here's an example of a timer definition block:

define timer <clock>
    interval <60>
    action set numeric <minutes; %minutes%+1>
    enabled
end define

The following lines may appear in a timer definition block:

action (script)

Specifies the script to execute every time the timer "fires".

disabled

Specifies that the timer is not running from the moment the game starts.

enabled

Specifies that the timer is running from the moment the game starts.

interval <(seconds)>

Specifies how much time elapses between each "firing" of the timer.

See also timeron, timeroff, set interval script commands; timerstate, timerinterval functions.


Types

Type Definition Blocks

Type definition blocks define a set of properties and/or actions. An object can then obtain all of these properties and actions by including a type tag in its definition block.

Type definition blocks are of the following form:

define type <type name>
    type <(another type name)>
    .
    .
    .
    property [ = (value) ]
    .
    .
    .
    action <(action name)> (script)
    .
    .
    .
end define

Type definition blocks themselves can include type tags, thereby allowing you to create sophisticated object types based on other object types. Any properties and actions specified will override equivalent properties and actions included by a type tag.

See the object properties tag for more information on properties, and see the object action tags for more information on actions.

Any define type <default> block will have all its properties and actions apply to all objects in the game. Similarly, any define type <defaultroom> block will have all its properties and actions apply to all rooms in the current game.

Within an action, you can find out which object is responsible for calling the script by using the $thisobject$ function, which will return the object name. The $thisobjectname$ function returns the object's displayed name. For example:

define type <edible>
    action <eat> {
        msg <You stuff the $thisobjectname$ in your face. Lovely.>
        move <$thisobject$; stomach> }
end define

define room <Dining Room>
    command <eat #@food#> doaction <#food#; eat>

    define object <chips>
        type <edible>
    end define

    define object <veg1>
        alias <potato>
        type <edible>
    end define
end define


Script Commands

All of the commands documented in this section can be used in any part of the code where some script code is required or allowed, for example in an object's "look" tag, the game's "afterturn" tag, and within procedures.

action <(object name); (action name)> (script)

Creates or replaces the specified action script for the specified object.

- see also object action tags

background <(colour)>

Changes the background colour to the colour specified. Valid values for the colour are white, black, red, green, yellow, blue. Players may override this by forcing a game to use Windows default colours, so don't rely on this command always working.

- see also foreground script command, foreground, background tags (game definition block), How to Format Text

choose <(selection block name)>

Shows the menu as defined by the specified selection block.

- see also the Selection Definition Blocks section

clear

Clears the text window.

clone <(object to clone); (new object name) [; (new object room) ]>

Creates an identical copy of the object specified with the new name specified. The new object will have an alias of the name of the old object, so both objects will appear identical to the player. (You can of course change the object's alias after cloning by setting its alias property). Unless you specify otherwise, the new object will be created in the same room as the old object.

conceal

see reveal

create ...

Creates a room, object or exit:

create exit [ north | south | etc... ] <(from room); (to room)>

Creates an exit in the direction specified from the "from room" specified to the "to room" specified. So,

    create exit north <hallway; bedroom>

would create an exit in the "hallway" room, north to "bedroom". In this example you'd probably also want to similarly create an exit south from "bedroom" to "hallway".

If the exit specified already exists (for example, there is already a way "north" from "hallway"), that exit will be replaced with what you specify here.

If no direction such as "north" is specified, the exit is created as a "go to..." type exit.

create object <(object name) [; (container room)]>

Creates an object with the specified name, in the room specified, if any. If no room is specified, the object does not exist within a room, but can be moved into a room as required using the move command.

create room <(room name)>

Creates the specified room.

debug <(debug text)>

Writes the specified debug text to the current Quest log file. This is useful for debugging purposes - you can write the contents of a specified variable to the log file whenever required, for example, to see where your code is going wrong.

displaytext <(name of text section)>

Displays the specified text block.

- see also the Text Blocks section

do <(procedure)[(parameters)]>

Executes the specified procedure, with any parameters specified. For example:

do <myprocedure>
do <eatthing(asparagus; tasty)>

- see also the Procedure and Function Blocks section

doaction <(object name); (action name)>

Executes the specified object's specified action script.

- see also object action tags

enter <(string variable)>

Overrides handling of keyboard input for the next turn. The next thing the player types will be put into the string variable specified, and will not be executed as a normal command. This is useful if, for example, you want the player to type something in when requested. For example:

msg <Enter your name:>
enter <playername>
msg <Hello there #playername#! How nice of you to be here.>

exec <(command) [;normal]>

Executes the specified command, just as if it were typed by the player, except that the command is not echoed to the screen (though its output is, of course). For example, exec <look at sign> would make Quest do the action associated with looking at the sign object in the current room, just as if the player had typed "look at sign".

A word of warning - if you use this as part of a command statement, you could feasibly end up in an infinite loop. The following example will cause Quest to hang:

command <take #object#> {
    if ( #object# = potato ) then do <specialtake(#object#)>
    else exec <take #object#> }

You may have coded the above, for example, if "potato" isn't a real object but you want Quest to react to "TAKE POTATO". However, if the player types another "TAKE" command, such as "TAKE LAMP", this will cause Quest to execute the exec statement, which will execute "TAKE LAMP", which will execute "TAKE LAMP"... Quest will end up in an infinite loop, causing it to hang.

In order that you don't end up hanging the interpreter when coding something like this, Quest has a normal parameter which will execute the command from Quest's built-in command set, disregarding all user-defined overrides of that command. To modify the above statement, you'd use:

command <take #object#> {
    if ( #object# = potato ) then do <specialtake(#object#)>
    else exec <take #object#; normal> }

This will cause the exec command to execute Quest's built-in form of the "TAKE" command, rather than the user-defined version which would normally have priority. This will mean no infinite loops, and Quest will behave as you'd expect.

When using the exec command, Quest will allow you to use real (i.e. unaliased) object names, whereas the player wouldn't be able to when using the command prompt. For example, if you have an object called BOOK01, with an alias of "book", the player can only refer to this object as "book". However, Quest will let you use exec <look at book01>.

font <(font name)>

Changes the current font to that specified. E.g.:

font <Verdana>

If no font name is specified, the font is set to the default font.

- see also default fontname and default fontsize in the Game Definition Block section and How to Format Text

for <(counter variable); (start value); (end value)[;(step)]> (script)

Executes the specified script for all integer counter variable values between the specified start and end value, in steps of whatever step value is specified (or 1, if no step value is specified). For example:

for <mynum; 7; 15; 2> msg <mynum reads %mynum%>

Here, the counter variable is the numeric variable "mynum". The start value is 7 and the end value is 15, and here we've specified a step value of 2. This means that the above command prints:

    mynum reads 7
    mynum reads 9
    mynum reads 11
    mynum reads 13
    mynum reads 15

You can "jump" out of the loop by setting the counter variable to a value equal to or higher than the end value within the script.

- see also repeat

for each object in { game | <(room name)> } (script)

Executes the specified script for each object, either in the whole game or in the specified room. Each time the loop script is executed, the current object is returned in the #quest.thing# string variable.

foreground <(colour)>

Changes the foreground colour (and hence the colour specified by the |cb formatting code) to the colour specified. Valid values for the colour are white, black, red, green, yellow, blue. Players may override this by forcing a game to use Windows default colours, so don't rely on this command always working.

- see also background script command, foreground, background tags (game definition block), How to Format Text

give <(object)>

Gives the specified object to the player.

- see also lose

goto <(room)>

Moves the player to the specified room.

helpclear

Clears the help window.

helpclose

Closes the help window.

helpdisplaytext <(text section)>

Used in the same way as displaytext, but prints to the help window rather than the main Quest window.

- see also displaytext

helpmsg <(message)>

Used in the same way as msg, but prints to the help window rather than the main Quest window.

- see also msg

hide <(object name)>

Hides the specified object so it does not appear and does not interact with the player.

- see also show, reveal / conceal

if [not] (condition1) [ { and | or } [not] (condition2) …] then (script) [else (script)]

Evaluates an expression or series of expressions. If true, the script after then is executed. If false, any script after else is executed.

If the conditions are separated by "and", all of the conditions have to return "true" for the script after "then" to be executed.

If the conditions are separated by "or", only one of the conditions need return "true" for the script after "then" to be executed.

Valid conditions are:

( (string/value) { = | <> | < | > | <= | >= } (string/value) )

This is the basic condition form and it takes an expression in brackets. e.g.:

    if (%myvariable% = 12) then msg <Twelve> else msg <Not twelve>
    if (#something# = blue) then do <blueprocedure>
    if (%somenumber% > 15) then picture <fifteen.gif; Over Fifteen>
    if (%something% <= 2) and (#place# = mansion) then playerlose else goto <mansion>
    if (%score% <> 100) then displaytext <notfullscore>

action <(object); (action)>

Returns a "true" if the specified object has the specified action defined.

ask <(question)>

Asks the player the question specified. If they select "Yes", a "true" is returned.

exists <(object name)[;report]>

Returns a "true" if the object exists; i.e. is a real object in the game that is available, in any room. The optional "report" parameter can be used if you want the ASL log to log any time this check is used and the object is unavailable due to it not being defined in the game. The related condition, real, does not check that the object is available, only that it is defined.

got <(object)>

Returns a "true" if a player has the specified object

here <(object name)>

Returns a "true" if the specifed object is in the same room as the player and is available.

is <(something); (another thing)>

Returns a "true" if the two things are the same. This has been superseded in Quest 3.0 and later by if (something = another thing), and is retained for compatibility.

property <(object); (property name)>

Returns a "true" if the object specified has the property specified.

real <(object name)[;report]>

Similar to the exists condition, but does not check that the object is available - only that it is defined in the current game.

type <(object); (type)>

Returns a "true" if the object specified is of the type specified (i.e. it includes the relevant type tag).

E.g.:

command <eat #object#> if got <#object#> and property <object; edible> then doaction <#object#; eat>

would allow the player to type "eat" followed by any object name. Then, if the player had that object and the object were edible, the object's "eat" action would be executed.

To prevent ambiguities caused by having if commands within if commands, you can use braces. For example there is ambiguity associated with:

if got <A> then if got <B> then msg <1> else msg <2>

Here it is unclear whether the else msg <2> belongs to the first if or the second if. Using braces makes everything clear:

if got <A> then { if got <B> then msg <1> else msg <2> }

Or,

if got <A> then { if got <B> then msg <1> } else msg <2>

lose <(object)>

Takes the specified object away from the player, if it is in their inventory, and puts it in the current room. If you want to take the object from the player and don't want it put in the current room, use hide instead.

- see also give

mailto <(email address)>

Starts the default email program for a message to the specified email address. Useful if you want to implement a feedback command, for example.

modvolume <(any number 0 to 100)>

Changes the volume that MOD files are played at. The default volume is 100, and you can change the volume while a file is playing.

- see also playmod

move <(object name); (new room)>

Moves the specified object to the specified room.

msg <(text)>

Prints the specified message.

- see also say

outputoff

Stops all text output to the Quest window. This is useful if you want to move the player to some location without displaying that location's description. Remember to turn output back on again using outputon, or the player won't be able to read anything.

- see also outputon

outputon

Turns output back on again after being turned off with the outputoff command.

- see also outputoff

panes { on | off }

Turns on or off the "panes" on the right-hand side of the Quest window.

pause <(milliseconds)>

Pauses the game for the specified number of milliseconds (1000 milliseconds = 1 second).

- see also wait

picture <(picture filename)[@(width)x(height)] [; (caption)]>

Shows the specified picture in the picture window. The file extension must be specified, as Quest supports a variety of picture formats - these are .BMP, .ICO, .RLE, .WMF, .EMF, .GIF and .JPG.

If a caption is specified, that caption is used for the window title, rather than the default "Picture". You can resize the picture by setting the width and height in pixels. For example:

picture <dragon.jpg@400x320; Dragon>

would show "dragon.jpg" with the caption "Dragon", resized to be 400 pixels wide by 320 pixels high.

- see also picture close

picture close

Closes the picture window.

- see also picture

playerlose

The player loses (and the text in the define text <lose> block is displayed)

- see also playerwin, stop

playerwin

The player wins (and the text in the define text <win> block is displayed)

- see also playerlose, stop

playmidi <(MIDI filename) [; loop]>

Plays the specified MIDI file in the game directory, or relative to it - note that the .MID or .MIDI extension is required. The MIDI file is played in the background. playmidi <> will stop any MIDI file from playing. Specifying the loop parameter will cause the MIDI file to loop.

playmod <(MOD filename) [; loop]>

Plays the specified MOD file in the game directory, or relative to it. The file extension must be specified. Quest supports all standard MOD formats including .MOD, .IT, .XM and .S3M. playmod <> will stop any MOD file from playing. Specifying the loop parameter will cause the MOD file to loop.

- see also modvolume

playwav <(.WAV filename) [; sync] [; loop]>

Plays the specified WAV file in the game directory (or relative to it - for example if the game is in C:\MY-IF\GAME1\ then playwav <wavfiles\welcome> will play C:\MY-IF\GAME1\WAVFILES\WELCOME.WAV). The file extension is optional - .WAV will be added if no extension is specified. Quest will silently ignore any attempt to play a non-existent file. playwav <> will stop any WAV file from playing. Specifying the loop parameter will cause the WAV file to loop.

Usually, Quest will start playing the WAV file and immediately return to the rest of the script, leaving the WAV to pay in the background. If the sync parameter is specified, Quest will wait for the WAV to finish before resuming processing - useful for things such as intros where you want some text to display after a sound ends, for example.

property <(object name); (property data ...)>

Changes the properties of the specified object. For example:

property <potato; not edible; age=15; smelly>

will turn off the "edible" property, set the age to "15" and add the "smelly" property.

- see also the object properties tag

repeat { until | while } (condition[s]) (script)

Repeats the specified conditions while, or until, the specified condition or conditions are true. The conditions you can specify here are the same conditions you can use for an if command. For example:

repeat until (#answer# = yes) or (#answer# = no) {
    msg <Do you really want to go into that big, dark pit? Answer YES or NO.>
    enter <answer> }

- see also for

{reveal | conceal} (object name)

reveal and conceal take the same parameters as hide and show etc., and act in a similar way. However, rather than being used in conjunction with the hidden tag of objects, these commands act with the invisible tag - so when you use conceal, the object is hidden but it is still accessible to the player and can be interacted with as before. This is different to hide, which would completely remove the object from the room so it couldn't be interacted with.

- see also hide, show

say <(text)>

Displays the specified text in quotes, as speech (do not type the quotes - everything inside the < > will automatically have " quotes " put around it).

- see also msg

set ...

set <(string or numeric variable name); (string or value)>

For an existing variable, changes the value or string contained in it. To declare a new variable use either set string or set numeric.

set interval <(timer name); (new interval)>

Sets the interval (in seconds) of the specified timer.

- see also Timer Definition Blocks

set numeric <(variable name); (value)>

Sets the value of the specified numeric variable. The "value" parameter supports basic math operations using two numbers/variables and the + (addition), - (subtraction), / (division) and * (multiplication) operators.

set string <(variable name); (string)>

Sets the string contained in the specified string variable. The "string" specified will be stripped of leading and trailing spaces. To set a string variable containing spaces, use [ ] characters around the whole string parameter. e.g. set string <space; [ ]>.

To read the contents of a string or numeric variable in any parameter, surround a string variable name with "#" characters and a numeric variable name with "%" characters.

Examples:

    set string <mytext; This is the text I'm storing.>
    set numeric <mynumber; 7>
    set <mynumber; %mynumber% + 7>
    msg <The text I stored was #mytext#.>
    msg <My number is %mynumber%.>

Notes:

  • When setting a variable do NOT use # or % characters around the string or numeric variable name. You only use # or % characters when displaying and comparing the value of variables.
  • If you attempt to read the value of a numeric variable that has not been set, a value of -32767 is returned and an error is logged into the current log file.
  • Division by zero results in an ASL logfile error message, and a message on-screen.
  • Quest only deals with integer numbers and variables. This means that a division by zero error can occur when evaluating expressions such as set numeric <mynum; %mynum%/0.5>.

setstring <(variable name); (string)>

Older form of set string, retained for compatibility.

setvar <(variable name); (value)>

Older form of set numeric, retained for compatibility.

shell <(filename) [;notactive]>

Shells (i.e., executes) the specified filename, which becomes the active window. The optional notactive parameter keeps the Quest window as the active window. If you want to run an EXE file that needs command-line switches, use shellexe instead.

Quest options will determine if a file is allowed to run - if a file fails to run, the reason will be logged into the current log file. A game can detect whether the last shell failed by examining the %quest.shellsuccess% numeric variable:

contents of %quest.shellsuccess% | meaning
0 | disallowed by Quest security options
1 | shell succeeded
2 | the file was not found
3 | no program could be found to open the specified file - files must be associated correctly in Windows Explorer in order to be able to be opened by the shell command
4 | out of memory

- see also shellexe

shellexe <(EXE filename) [(command-line switches)]>

Executes the specified EXE file, with command-line switches if specified. As for shell, the player's Quest options will determine if the EXE file is allowed to run.

- see also shell

show <(object name)>

Shows the specified object - the opposite of hide.

- see also hide, reveal / conceal

stop

Finishes the game. Unlike playerwin and playerlose, this does not automatically print any text sections.

- see also playerwin, playerlose

timeron <(timer name)>

Turns on the specified timer.

- see also timeroff, Timer Definition Blocks

timeroff <(timer name)>

Turns off the specified timer.

- see also timeron, Timer Definition Blocks

type <(object name); (type name)>

Adds all the properties and actions of the specified type to the specified object.

- see also object type tags, Type Definition Blocks

wait [<[(wait message)]>]

Waits for the user to press a key before continuing execution. Useful when printing large amounts of text to the screen for example. If used on its own without any parameter, wait will print the default "Press any key to continue...". If used with an empty parameter (i.e., wait <>), wait won't print anything. If there is text in the parameter, wait will print that instead of the default text.

- see also pause


Built-in Functions

Quest has several useful internal functions for string handling etc. These should all be used inside parameters for other tags or script commands, as they return a value - they don't do anything on their own. For example, a use of the $loadmethod$ function is:

if ( $loadmethod$ = normal ) then displaytext <longintro>

And a use of the $capfirst(...)$ function is:

msg <Enter your name:>
enter <playername>
set string <propername; $ucase(#playername#)$>
msg <Hello there #propername#!>

Game Functions

$displayname(object name)$

Returns the displayed name of an object, when passed the real name of an object. A shortcut is to use #@(object name)#. For example,

$displayname(object001)$

and

#@object001#

both return the same thing - namely, "object001" if the object called "object001" has no alias, or its alias if it does have one.

$getobjectname(object name [; container room])$

This is the opposite of $displayname(...)$. This returns the actual name of an object from the displayed name, and it can be used when processing player input for object names. If there is an ambiguity (i.e. when two or more objects have the same alias), it displays the standard Quest disambiguation menu and the player is asked to choose which object they mean. By default, Quest will check for the object in the current room and in the inventory, unless you specify a container room, in which case Quest will check that instead (you can make Quest check the inventory as well by adding ;inventory to your container room, e.g. $getobjectname(myobject; someroom; inventory)$). The use of this function has now been largely superseded by the use of the #@...# form in command statements, introduced in Quest 3.1 - see How To Add Your Own Commands to a Game for full details. This means that:

command <ignite #@thing#> doaction <#thing#; ignite>

is equivalent to the older, and lengthier form which uses the $getobjectname(...)$ function:

command <ignite #thing#> doaction <$getobjectname(#thing#)$; ignite>

$loadmethod$

Returns "normal" if the game was loaded from new; returns "loaded" if the game was restored from a QSG file. Use this function in your startscript for example - if "loaded" is returned, there's no need to display any introduction text or play any intro sounds.

$locationof(object name)$

Returns the location of the specified object (the name of the room that it is currently in).

$objectproperty(object name; property name)$

Returns the value of the specified property of the specified object. Returns "!" and reports an ASL error if the specified object or property does not exist. A shortcut to using this function is to use the #...:...# form introduced in Quest 3.1 - see Reading Properties for more information.

$timerinterval(timer name)$

Returns the timer interval of the specified timer, in seconds. Returns "!" if the timer name specified does not exist.

- see also Timer Definition Blocks, set interval.

$timerstate(timer name)$

Returns "1" if the specified timer is on, "0" if the specified timer is off, and "!" if the timer name specified does not exist.

- see also Timer Definition Blocks, timeron, timeroff.

String Handling and Variable Functions

$capfirst(string)$

Capitalises the first letter of the string passed to it. E.g.:

$capfirst(bill)$

returns "Bill"

$instr([start position;] search string; string to find)$

Returns the position of the start of the specified string to find within the search string, optionally starting the search from the specified start position. E.g.:

$instr(Potato to go;to)$

returns "5"

$instr(6;Potato to go;to)$

returns "8"

If you want to search for something that has spaces at the beginning and/or end - for example, the single word "to" in the above example rather than "to" as a part of the word "potato" - you'll need to search for something like " to " - however, Quest will automatically strip function parameters of leading and trailing spaces. To get around the problem, use the underscore character "_". So, to search for the single word "to" in the above examples, use:

$instr(Potato to go;_to_)$

which returns "8".

$lcase(string)$

Returns a lower-case version of the string passed to it. E.g.:

$lcase(thIs sTRinG)$

returns "this string"

$left(string;length)$

Returns the specified number of characters from the left of the string. E.g.:

$left(Hello there!;5)$

returns "Hello".

$lengthof(string)$

Returns the length of the specified string. E.g.:

$lengthof(Hello there!)$

returns 12.

$mid(string;start;length)$

Returns the middle characters from the specified start point up to the length specified. E.g.:

$mid(Hello there world!;7;5)$

returns "there".

Note that length can be omitted - Quest will then return the rest of the string from the "start" position. E.g.:

$mid(Hello there world!;7)$

returns "there world!".

$right(string;length)$

Returns the specified number of characters from the right of the string. E.g.:

$right(Hello there!;6)$

returns "there!".

$ubound(variable name)$

Returns the upper bound of the specified array.

$ucase(string)$

Returns a capitalised version of the string passed to it. E.g.:

$ucase(thIs sTRinG)$

returns "THIS STRING"

Miscellaneous Functions

$rand(num1;num2)$

Returns a randomly chosen number between the specified num1 and num2. E.g.:

$rand(4;7)$

will return 4, 5, 6 or 7.

$symbol(symbol code)$

Prints a symbol.

This function accepts two symbol codes - "gt" returns a greater-than sign ">", and "lt" returns a less-than sign "<". These cannot be normally typed into parameters as these characters form the start and end points of parameters - msg <You see a sign: < Brussels London >> would severely confuse the Quest code parser, so the above should be coded as:

msg <You see a sign: $symbol(lt)$ Brussels London $symbol(gt)$>

Parameter Functions

Parameter functions are used for functions and procedures you write yourself. Within these functions and procedures, you can find out how many parameters were passed to it and what they were:

$numberparameters$

Returns the number of parameters passed to this function.

$parameter(parameter number)$

Returns the specified parameter.

For example, if you call a procedure using do <myprocedure(My text; 5)>, then your procedure definition might look like:

define procedure <myfunction>
    if ( $numberparameters$ < 2 ) then msg <error>
    else {
        for <i; 1; $parameter(2)$> msg <$parameter(1)$> }
end define

The procedure would then print the text "My text" five times.


Built-in String Variables

Quest has several built-in strings which can be accessed in the same way as normal strings. These strings are:

quest.command

As quest.originalcommand, but after synonyms have been calculated - so, for example, if "read" is specified as a synonym of "examine", and quest.originalcommand contains "read the book", quest.command will contain "examine the book".

quest.currentroom

Returns a string containing the "real" name (i.e. proper code name) of the current room. quest.formatroom returns the displayed version of the room name.

quest.doorways.dirs

Returns a list of directions that can be used, eg. "north, west".

quest.doorways.places

Returns a list of places that the player can access by typing "go to ..."

quest.doorways.out

Returns the real name of the place that the player will exit to if he/she types "out"; otherwise is empty.

quest.doorways.out.display

Returns the displayed name of the place that the player will exit to if he/she types "out"; otherwise is empty.

quest.formatobjects

Returns a text-formatted list of objects in the current room.

quest.formatroom

Similar to quest.currentroom, but returns the displayed name of the room - so if an alias has been used, this will return the alias, and if a prefix has been used, a prefix is included.

quest.lastobject

Returns the (real) name of the last object that the player referred to in a command.

quest.lookdesc

Returns the current room's description as specified by its look tag.

quest.objects

Returns a list of objects in the current room.

quest.originalcommand

Returns the command the user just typed (converted to lower case). quest.command returns the command after processing for synonyms.

For example:

if ( #quest.currentroom# = library) then msg <You are in the library>

will print "You are in the library", if you’re in the library.

The string variables above are especially useful when customising room descriptions - they give access to information such as the doorways present, things in the room, etc. which can be printed on the screen. See How to Customise Room Descriptions for more information.


Quest Methods

Changing an Object's Behaviour

Reading Properties

Using Libraries
- QDK Library Interfacing

Using Arrays

About Rooms and the Inventory


Changing an Object's Behaviour

Properties

You can change an object's alias, prefix, description and more by altering its properties using the property script command - see list A below. You can also read tags such as an object's look tag in the same way as you'd read an object property - for example #lamp:look# returns the lamp's look tag. See list B for the full list of tags which can be read using the property method.

List A. You can change the following object tags with the property command:

  • look
  • examine
  • alias
  • prefix
  • suffix
  • detail
  • hidden (boolean property, i.e. can only be either "hidden" or "not hidden")
  • invisible (boolean property, i.e. can only be either "invisible" or "not invisible")
  • displaytype
  • indescription
  • description
  • speak
  • gender
  • article

List B. You can read the following object tags in the same way as you can read properties:

  • look
  • examine
  • prefix
  • suffix
  • detail
  • displaytype
  • gender
  • article

So, to change an object's "look" description during the game, you could use for example:

property <rug; look=This rug has got a nasty stain on it.>

Rooms in Quest can also take properties, so you can also change room descriptions in the same way.

You can set default prefix, look etc. tags (everything in List A) for everything in the game by adding these properties to a define type <default> block.

Actions

The following object actions take precedence over equivalent object tags, and equivalent object properties (if appropriate):

  • look
  • examine
  • speak
  • take

You can also change an object's "use" and "give" behaviour while a game is running by changing its actions, using the action script command:

Use...

action <object name; use> (script)
action <object name; use 'other object name'> (script)
action <object name; use on 'other object name'> (script)
action <object name; use anything> (script)
action <object name; use on anything> (script)

Are equivalent to changing the following tags, respectively:

use (script)
use <other object name> (script)
use on <other object name> (script)
use anything (script)
use on anything (script)

Give...

action <object name; give> (script)
action <object name; give 'other object name'> (script)
action <object name; give to 'other object name'> (script)
action <object name; give anything> (script)
action <object name; give to anything> (script)

Are equivalent to changing the following tags, respectively:

give (script)
give <other object name> (script)
give to <other object name> (script)
give anything (script)
give to anything (script)


Reading Properties

There are two ways of reading properties of an object, room or game which return a value. (For properties without a value, i.e. those which are always either "on" or "off", see the if property statement).

The easiest way is to use the string-variable-like #...:...# form. The syntax of this is:

#(objectname):(property)#

For example, if you have an object called "cod" and it has a "smellstrength" property, you could read this in an msg command using:

msg <The cod has a smell strength rating of #cod:smellstrength#.>

If the object name needs to be a variable - for example, you want to add a SMELL command that the player can use to get the smell strength of any object - put the variable name in brackets as the object name. For example:

command <smell #@thing#> {
    msg <The $displayname(thing)$ has a smell strength rating of #(thing):smellstrength#.>
}

An alternative way of accessing object properties is using the $objectproperty(...)$ function. Using this function, the above example translates to:

command <smell #@thing#> {
    msg <The $displayname(thing)$ has a smell strength rating of $objectproperty(#thing#; smellstrength)$.>
}


Libraries

Using Libraries

Sometimes you come up with some really useful ASL code that would be useful in all of your games and maybe handy to other game authors. In this case, you'll want to create a library - then you'll be able to reuse it in any game you make, and perhaps distribute it to other people so they can use it in theirs.

A library is similar to a normal ASL file in that it consists of "define" blocks, containing procedures or even rooms and selection blocks. This is then usually saved as a .lib file, and it can then be included in any game simply by adding:

!include <(library file name)>

to the game's .asl file. All included libraries then basically become part of the game file, and their procedures and rooms can be called in just the same way as if they were part of the game's own code.

You can also include other libraries from within libraries, using the normal !include statement. Quest will not add the same library twice to a game, so it is quite safe to include any popular library from within your library if it requires it, without needing to worry about whether any other library or the game itself will include it.

All libraries must begin with these lines:

!library
!asl-version <311>

These tell Quest that the file is a valid library. The !library must be on the very first line - !asl-version can appear anywhere in the file.

!addto blocks

Sometimes with a library, you'll want to add some lines that will be included as though they were part of the including game's "define game" block - for example, you might want your library to add a startscript to the game, or to add some commands to the game. If this is the case, you need to use an !addto block. Enclose the lines with:

!addto game

at the beginning, and

!end

at the end. If you merely included your own game definition block in the library, this would become separate to the game's own game definition block and would therefore be ignored. All !addto blocks follow this basic form.

When you use !addto game, you can include a startscript. This will be executed before any startscript specified by the main game ASL file.

Similarly, to add synonyms to a library, enclose the lines to add with:

!addto synonyms

and

!end

A game can add properties and actions to the default and defaultroom types using !addto type <default> and !addto type <defaultroom> blocks.

Creating Libraries for QDK Users

Libraries can add interface elements to QDK, for authors using QDK. This makes it much easier for game authors using QDK to use your library. See QDK Library Interfacing for information.

Example:

!library
!asl-version <311>

!addto game
    command <eat #@object#> doaction <#object#; eat>
!end

!addto synonyms
    consume; munch = eat
!end

define procedure <multiprint>
    for <i; 1; $parameter(2)$> msg <$parameter(1)$>
end define

This adds "EAT", "CONSUME" and "MUNCH" commands to a game, and adds a "multiprint" procedure, which would print out its first parameter the number of times specified by its second parameter.


QDK Library Interfacing

New in QDK 3.1 is the ability for a game's included libraries to add elements to the QDK windows. Categories can be added to the Script Command Editor, and panes for extra information can be added to the object, room and game properties windows.

A library interface description section of a library file needs to begin with the line "!QDK" and end with "!end". You can actually add extra characters after these lines, if you wish, to separate this section visually in your library code. For example:

!QDK ========================================================================

(interface data goes here)

!end ========================================================================

Adding To The Script Command Editor

You can add categories to the Script Command Editor with additional "commands" in them, and these will be translated into calls to procedures. Here is an example that defines a "Funky Library" category with two "commands" in it:

script <Funky Library>
        command <Detonate bomb object; detonate>
                parameter <Bomb object; objects>
                display <Detonate "|cl$1|cb">

        command <Write graffiti; graffiti>
                parameter <Write on object; objects>
                parameter <Text; text>
                display <Write "|cg$2|cb" on "|cl$1|cb">

Note there is no "end script" or "end command" - the "command" tag applies to the category defined above it, the "parameter" tags to the command defined above them, etc.

The parameter of "script" specifies the name of this category to display on the Script Command Editor.

The command tag takes two parameters - the first is the title of the command as displayed in the Script Command Editor, and the second is the name of the procedure that this "maps" to. In our example, "Detonate bomb object" refers to the "detonate" procedure, and "Write graffiti" refers to the "graffiti" procedure.

For each command you need to specify the number of parameters it takes, and how to display this command outside of the Script Command Editor. The parameter tag takes two parameters - the first is the prompt for this parameter, and the second is the parameter type. A parameter type of "objects" will display a drop- down list of objects, and "text" will be a simple text box. The valid types are:

parameter type | displays
text | a simple one-line text box
bigtext | a large multi-line text box which fills the parameter box on the Script Command Editor (useful for large passages of text)
textblocks | a list of text blocks
procedures | a list of procedures
menus | a list of menus
rooms | a list of rooms
objects | a list of objects
objsrooms | a list of objects and rooms
timers | a list of timers

Next, the display tag specifies how this command is displayed, on the main Script Editor window (the first window that appears when you click an "Edit" button) and when displayed on windows such as the Object Properties window. The parameter consists of a string with additional formatting codes. You can use the same string formatting codes as you can use in Quest. To be consistent with the style normally used, you should use green text for strings of text and blue text for the names of things such as objects. $1, $2 etc. are placeholders for the values of parameters 1, 2 etc.

In our example for the "graffiti" procedure, our display string is

Write "|cg$2|cb" on "|cl$1|cb"

If the user has entered or selected "wall" at the "Write on object:" prompt, and typed in "anarchy" at the "Text:" prompt, this will display:

Write "anarchy" on "wall"

with "anarchy" in green text and "wall" in blue text.

Formatting codes are stripped out on the Script Editor window, and the above text would appear entirely in black.

Here's an example of what the author will see. Let's say the author has included this library in a game, and now wants to add a command that allows the player to write graffiti on a wall. The author then goes to set up the command by going to Game Properties, Global Settings, Edit Custom Player Commands, Add, then entering "write #text#" as the command name. They now click Edit to edit the script that will be executed when the player types in this command. They click the "Add Command" button on the Script Editor, and the Script Command Editor window loads. As this library has been included in the game, the author will see that a "Funky Library" category has been added to the commands list. When the game author selects this category and selects the "Write graffiti" command, they will see a screen like this, where they might fill in the parameters as shown:

When they click OK on the Script Command Editor, they see the Script Editor again, which now shows this new command has been added to this script:

Happy with this, they click OK again and are returned to the "Edit Command" window, which now looks like this:

When this is saved, the following line will appear in the game definition block of this ASL file:

command <write #text#> do <graffiti(wall; #text#)>

As far as the game author is concerned, they accessed the graffiti-writing routine just as they would access any other script command - but this time, this "script command" is actually referring to a call to a procedure, but it is a procedure that the game author does not need to know how to call. By adding a declaration for QDK interface elements to our library, we have eliminated the need for the game author to trawl the documentation to get to grips with special code, and we have therefore not made the game editing process any more complicated.

Adding To The Object, Room And Game Properties Windows

Interface elements on the object, room and game properties windows map to corresponding properties, actions and types for the object, room and game definition blocks. The concept of having properties etc. in the game definition block is new in Quest 3.1. You can access the properties and actions of a game by referring to the "game" object in the normal way.

You can add a pane to the object, room or game properties windows as in the following examples:

object <Food>
        property <&Tastes nice; tasty>
        property <&Flavour description; flavour; text>
        action <&Eat script; eataction>

room <House Rooms>
        type <Living room; livingroom>
        type <Dining room; diningroom>
        type <Bedroom; bedroom>
        type <Bathroom; bathroom>
        type <Kitchen; kitchen>
        property <Size (sq.ft.); size; text>

game <Things>
        property <Player's favourite thing; fave; objects>

These examples add a "Food" pane to the object properties window, a "House Rooms" pane to the room properties window and a "Things" pane to the game properties window.

As with script categories there is no "end room" or similar - properties, types and action apply to the pane defined above the tag.

Property tags

Property tags take either two or three parameters. If two parameters are specified, this interface element corresponds to a boolean property ("something", "not something") and a checkbox appears. The first parameter specifies the prompt to display on the window (the ampersand "&" character specifies a mnemonic - in our object pane example, the user can press Alt+F to edit the "Flavour description" - "F" being the character that appears immediately after the "&"). The second parameter specifies the name of the property that this interface element maps to.

If there is a third parameter, this specifies that this property is one that takes a value, and this third parameter specifies what type it is. It can be any of the same types that can exist in the script "parameter" tag e.g. "text", "objects", "objsrooms" - see above.

Action tags

Here, the first parameter is the prompt to display (which can again contain a "&" for a mnemonic) and the second parameter is the name of the action that this corresponds to.

Type tags

Again the first parameter is the prompt to display, and the second is the type name that it corresponds to. This will appear on the window as a checkbox.

The order that the various property, action and type tags appear in is the order in which the various interface elements will appear on the interface.

Here's an example which adds a pane to the Object Properties window:

object <Beverage>
        type <&Alcholic drink; alcoholic>
        type <&Carbonated; fizzy>
        property <&Volume (ml); volume; text>
        action <&Drink script; eataction>

When this library is included in QDK and the author goes to the Object Properties window, they will be able to select a "Beverage" pane, which looks like this:

By filling in the relevant details, the "alcoholic" type could be set, the "volume" property could be given a value, etc., for this object. Again, the author doesn't need to know that to make an object be a carbonated drink, they need to set it to be of type "fizzy", so we have opened up the power of our library to QDK users without requiring them to know the names of the properties, types and actions that are used by it. We have made using our library as intuitive as possible, so that using its features is no different to using any of Quest's built-in features.


Arrays

Using Arrays

Arrays are groups of related variables which share the same name but are distinguished by an "index" number. For example, you might store the months of the year in an array - month[1] would be "January", month[2] would be "February", etc.

It's simple to set up an array in Quest - there's no need to declare it before you use it. For example, for our months array, we could use:

set string <month[1]; January>
set string <month[2]; February>
set string <month[3]; March>
.
.
.
set string <month[12]; December>

We can then read the contents of our array in exactly the same way as we can for ordinary string or numeric variables. For example:

msg <Month 6 is #month[6]#.>

So far this does not actually add anything new - after all, there's nothing to stop us creating variables such as #month6# or #monthsix# anyway. But arrays come into their own when you need to use another variable to look at the contents of a particular element of the array. For example, we might want a user to be able to type a number from 1 to 12 and report back the correct month. This would not be possible without arrays (unless we typed in a lot of very tedious code). But with arrays it becomes easy:

msg <Enter a number from 1 to 12:>
enter <number>
' "enter" returns a string variable so convert to a numeric variable:
set numeric <monthnumber; #number#>
msg <Month number %monthnumber% is #month[monthnumber]#.>

Note that we do not use the normal "%" characters around monthnumber when it appears as the array index.

Another, simpler, example is printing out all twelve months:

for <i;1;12> msg <#month[i]#>

The upper bound of an array is the highest index that has been set. In our example the upper bound is 12, because month[12] is the highest array index we have set. If we try to get the value of #month[15]# we will get an error. Out-of-bounds numeric arrays also generate an error, and return -32766 (in a similar way that non-existent numeric variables report an error and return -32767). The upper bound of an array can be obtained by calling the ubound function.


About Rooms and the Inventory

The Inventory

Rooms are handy because they can contain objects. One special room is inventory - this is the room where all objects that a player has picked up live. This means that the following two Quest commands are (mostly) equivalent:

give <someobject>

and

move <someobject; inventory>

(An exception to the commands being equivalent is that the example using move won't execute any gain script that this object has specified)

If you want to take an object from the player, the lose command will put that object in the current room, just as if the player had dropped it. If you don't want that to happen, you could hide the object instead - the player will no longer have access to that object, as hiding it is tantamount to completely removing it from the game.

Storing Objects

One thing about rooms that you might find handy is that you don't actually need to define them if you just want to put objects in them. You might want to use a room so that a character in your game could have its own inventory - the player never needs to be inside this room, so there's no need to define it, and you can use:

move <someobject; peter-inventory>

whether a room called "peter-inventory" has been defined or not.

Unique Names

Rooms must have unique names in Quest, and, as rooms can have properties and actions associated with them, no room can have the same name as an object, to avoid ambiguity when we use things like the property command. This is why we didn't call the room in our above example "peter" - Peter and his inventory are two separate things.


How To...

Add Your Own Commands to a Game

Format Text

Customise Room Descriptions

Hide Your Game Code

Create a Help Guide

Split Long Lines


How To Add Commands

How To Add Your Own Commands to a Game

Adding your own commands can be very useful if you want the player to do something specific to the game which Quest doesn't have built-in support for - for example you might want the player to be able to type "READ BOOK", or have them able to eat something or write on something. In Quest, these are very simple to implement - just add a command statement, either to the game definition block (if you want the command to apply throughout the whole game), or to a specific room definition block (if you want the command to apply only when the player is in that room).

Typically in a command, there are some keywords that must be present, for example "read" or "eat", and some variable or variables which represent either an object specified by the player (such as "book", "apple"), or some other text specified by the player (such as the player's name, or some message they want to write on something).

Syntax

The command statement takes the general syntax:

command <... #variable1#... #variable2#...> (script)

where "..." represents a word or number of words that the user must type in for this command. "#variable...#" represents a string variable, and the text that the user types in that place will go into the string variable specified. You can specify multiple commands on the same line by separating them with semicolons.

A simple example is:

command <say #text#> msg <I say, that's nice!>

Now, whenever a player types anything starting with the word "SAY", whatever they type after it will be put into the "text" string variable, and the script "msg <I say, that's nice!>" will be executed. So, if they player types "SAY HELLO", the script will execute with "HELLO" put into the string variable "text". Our script might then access that variable to say something to the player - see the extended example below.

For text, things are that simple, but if we want the player to specify an object name, it's a bit more complicated, as this object may have an alias - that is, in your game's ASL code it may have a different name to the name that is presented to the player. An object called "thing002" might be called "book" to the player, so we need a way for the player to be able to type "book" and have this automatically translated to "thing002" for the purposes of our script. This is accomplished by prefixing the variable name with the "@" symbol - think of it as standing for "alias" or "object".

Including the "@" symbol means that:

  • Quest will automatically disambiguate object names. That is, if there are two objects with the same alias or alt-name, Quest will ask the player which object they are referring to before putting the "real" object name in your specified string variable and running the script.
  • the script won't run if a non-existent object is specified - the player will get the standard error message telling them that that object doesn't exist.
  • the player can type "OOPS ..." to correct a command (if they've typed a non-existent object name), just as they can for standard Quest commands.

Although for simple games that don't use any aliases, omitting the "@" will cause no problems (as what the player thinks an object is called, and what Quest thinks an object is called, are exactly the same thing), it's not a habit we recommend you get into. Plus you'll miss out on the user-friendliness of Quest telling the player that there's no such thing as a "BOK".

When you later refer to this variable in your code, whether or not you included the "@" in the command statement, the variable is usually accessed in the same way - that is, the "normal" #...# form without using the "@" symbol. (See the extended example below for an examples of when we use the #...# form and when we use the #@...# form).

We can mix the two forms of variable in one command if we wish, although normally we only use one variable in a command anyway.

An example

Here's an example which should hopefully make it all clear:

define room <canteen>
    define object <fooditem001>
        alias <beans>
        properties <edible>
        look <Glorious baked beans.>
    end define

    define object <chips>
        properties <edible>
        look <Delicious, chunky potato chips, fried to perfection.>
    end define

    define object <Andrea>
        speak say <Yes! What do you want?>
    end define

    command <ask andrea for #@food#; request #@food#; give me #@food#> {
      ' see below for an explanation of why we use #food# some times, and
      ' #@food# at other times.
        if property <#food#; edible> then {
            give <#food#>
            msg <You put the #@food# on to your tray.> }
        else say <I don't think you'll be able to manage that, dear.>
    }

    command <say #text# to andrea; say #text#> {
      ' here, we always use #text#, as there is no object name to disambiguate -
      ' all we are interested in is the raw text.
          msg <You say "#text#", but Andrea isn't listening.>
    }
end define

This example sets up a canteen with two choices of food in it. The player can type "ASK ANDREA FOR ..." followed by the name of any food item, or also "REQUEST ..." or "GIVE ME ...". The script after the command statement checks whether the item requested is edible, and then acts accordingly. If you specify an item of food that doesn't exist, the default Quest "badthing" error is printed, and the script doesn't run.

Two ways of referring to a string variable

In the example above, note that we have an object called fooditem001. This has an alias "beans". Now, in our code, we must always refer to this object as fooditem001, because that is its name in our code. However, the player doesn't know what fooditem001 is - as far as the player is concerned, this object is called "beans". (Of course, usually if we were to have a small game like this, we would just call the object "beans" in our code anyway, but when you have a bigger game, or objects are created on the fly, you may find that what the player calls your objects is not what your code calls the same objects - you might have several objects you want the player to call "beans", but you have to call them separate names in code).

So that we don't end up asking Quest to do something to the non-existent object beans, and so that we don't end up with our character "Andrea" talking to the player in jargon about "fooditem001", we have to use two different ways of referring to the one string variable named food, which tells us what the player typed in. Because we want "beans" to be automatically converted to fooditem001 for our code should the player type in "beans" in the "ASK ANDREA FOR..." command and its relatives, we refer to the food string variable using the #@...# form (i.e., "#@food#") when setting up the command - see the command lines in the example.

A few lines down we then check whether the item that the player typed in is edible, by seeing whether it has an edible property set. In this case we need to check for the property using the code object name, which would be fooditem001 for our aliased "beans". This means we use the #...# form for the "if property ..." line in the example.

We then use the #...# form for the give command which moves the item to the player's inventory. However, we then want to print a message telling the player that they have put the item onto their tray - and, since this is text that is presented to the player (and not used in code for actually doing anything to this object), we use the #@...# form - so if we just moved fooditem001 to the player's inventory, we want to tell the player that they put the beans onto their tray - not that they put the "fooditem001" on their tray!

Our other object, chips, has no alias - it is called chips in code, and the player will refer to it as "chips". In this case, when the player types ASK ANDREA FOR CHIPS, both #food# and #@food# will return the same thing ("chips"), as you would expect.

As for our "SAY ..." command, whatever the player types here will have nothing to do with objects - so we use the #...# form, as we don't want any conversion of any kind to take place. Also, if we used the #@...# form for our command statement, the command would only work if the player wanted to SAY BEANS or SAY CHIPS, and we wouldn't want to limit our players' vocabularies quite so drastically.

Further Examples and Priorities

If, in our example, Andrea got annoyed at rude customers and we required the player to type something like ASK ANDREA FOR BEANS POLITELY instead, we could use a statement of the form:

command <ask andrea for #@food# politely> (script)

You can have even more flexible command statements, writing to more than one string variable:

command <make #thing# with #@object#> ...
command <put #@thing# and #@otherthing# in #@container#> ...
command <write "#text#" on #@surface# using #@object#> ...

You can override any command that exists throughout the game in a particular room by defining a command of the same form in that room's definition block. The priority of finding commands that fit what the player types in goes from the top of the current room definition block to the bottom, then to the top of the game definition block to the bottom. In our example with Andrea in the canteen above, if we wanted to implement the "ask ... politely" form of the command we would have to do this above the non-polite command definition - otherwise we could find the player asking Andrea whether they could have some "beans politely" for lunch, and that could be embarrassing.


How to Format Text

Text formatting can be used for absolutely anything that outputs text - object descriptions, text blocks, msg text, etc.

To add formatting to text, insert a pipe character ("|" – on UK keyboards this is usually to the left of the "Z" key, on the same key as "\"; on US keyboards I believe it is usually above the Return key) followed by the relevant formatting code:

Code | Text formatting
|b | bold on
|xb | bold off
|u | underline
|xu | underline off
|i | italic
|xi | italic off
|cb | black, or current foreground colour
|cr | red
|cl | blue
|cy | yellow
|cg | green
|sxx | change font size to xx - anything from 01 to 99
|s00 | revert to default font size
|jl | set text to left-justified
|jc | set text to centered
|jr | set text to right-justified
|n | new line
|xn | (at end of msg text only) no new line
|w | wait for keypress
|c | clear screen

The |cb formatting code traditionally stands for black, but the foreground colour may be changed (by the foreground tag in the game definition block, or by the foreground script command), and so this code now always corresponds to the current foreground colour. By default this is black, and some players may have their options set so this is always black.

For example:

msg <|b|crSTOP!|cb|xb There is a |ireally|xi big, |cggreen|cb thing here.>

would display:

STOP! There is a really big, green thing here.

The |xn code is a special case and can only be used at the end of a line of text displayed with the msg command. This will mean that the next text displayed will appear on the same line, and is useful if you want to conditionally print something. For example:

msg <You have |xn>
if ( %gold% >= 5 ) then {
    msg <over five pieces of gold, and you may enter.>
    goto <party> }
else msg <not got enough gold. Go away.>

Default fontsize is dependent on user settings and the contents of default fontsize in the game definition block.

When specifying formatting for a line, don't forget to turn it off! If you don't, all subsequent text, even Quest's error messages such as "Unrecognised command", will be displayed with the formatting specified. The only formatting codes that do not need to be turned off are |n, |xn, |w and |c. To "turn off" colours, use |cb to change the text back to the default foreground colour.

Note that you can only use one justification tag per line - if you use "|jcWelcome to my Game|jl", the "Welcome to my Game" text will be printed left-justified rather than centred. Instead, you should use "|jcWelcome to my Game" on one line, and "|jl" on the next. If you have no further text to print, use "|jl|xn" to change the justification without printing a new line.

|w and |c are useful when displaying large amounts of text in a text block. |w will wait for a keypress (note that no message is printed, unlike with the wait script command - you should add "Press a key to continue..." etc. yourself to the text section before the |w code), and |c will clear the screen (useful after the |w code).

Don't be dependent on font type, size or colour for anything - ASCII art, for example, is doomed to failure as the Quest window size can be changed by the player, and font size, type and colour commands can be set up to be ignored from the player's options.


How to Customise Room Descriptions

Quest's default room descriptions of printing the player's location, followed by a list of the objects in the room, and then the available doorways, can be rather unimaginative, with the only place for author creativity in the look line.

Fortunately, the descriptions can be overridden and turned into something that looks better to the player, if required.

It may be that you just want to change how Quest's room descriptions look - in this case, you'd want to override the descriptions globally by placing some description script in the "define game" block.

The following is an example "description" line that will print a description fairly similar to the default Quest one. It makes heavy use of Quest's internal strings and functions. Feel free to use it (or a modified version of it) in your own games:

description {
    set string <indescription; $gettag(#quest.currentroom#;indescription)$>
    if is <#indescription#;> then set string <indescription; You are in>
    else {
        set numeric <len; $lengthof(#indescription#)$>
        set numeric <len; %len%-1>
        set string <indescription; $left(#indescription#;%len%)$>
    }
    msg <#indescription# |b|cl#quest.formatroom#|xb|cb.>
    if not is <#quest.doorways.out#;> then msg <You can go out to #quest.doorways.out#.>
    if not is <#quest.doorways.dirs#;> then msg <You can go #quest.doorways.dirs#.>
    if not is <#quest.doorways.places#;> then msg <You can go to #quest.doorways.places#.>
    if not is <#quest.objects#;> then msg <You can see #quest.formatobjects#.>
    msg <#quest.lookdesc#>
}

A change in Quest 3.1 is the final line - msg <#quest.lookdesc#>. Previous versions automatically appended the current room's look tag to the description, but this is now not the case as long as you set asl-version to 310 or greater. Now you can specify exactly where and how you want the look description displayed, by printing the contents of the new #quest.lookdesc# string variable where you want it.

An alternative, and more classical way of making room descriptions is for the game author to write all aspects of the description. For example, you might want to write something like this for each room in your game:

"You are standing outside a magnificent castle, in front of a huge iron portcullis which lies to the north. You can hear voices above you."

In this case, you'd simply have to put all of that inside a parameter for the description line in the relevant room definition block. Quest's default room description is then overridden and you don't get all of that beautiful prose spoiled by "You can go north. There is nobody here." etc.


How To Hide Game Code

How to Hide Your Game Code

If you've been working hard on a game, the chances are that you don't want people to just take a quick peek through the code to get at the solutions. The way around this is to compile your ASL script into a CAS (Compiled Adventure Script) file. If viewed in a text editor, hex editor, etc. this appears as meaningless rubbish - no text is viewable. Quest, however, can decrypt these files and execute them, just as it does with ASL files.

To convert an ASL file to a compiled CAS file, you need to use the QCOMPILE.EXE utility, which is included with Quest Pro only. If you are a registered user of Quest Pro, you just need to fire up this program, click Browse to find the ASL file you wish to compile, choose a CAS filename (the default is the same name as the ASL file but with the .CAS extension), then click Compile. Depending on the speed of your PC and the size of the ASL file, the compile could take anything between a few seconds and a minute or so.

If you are not a registered user of Quest Pro, click here to upgrade.

See the QCompile Manual for more information.


How To Create Help

How to Create a Help Guide

If you don't like the text displayed when the "HELP" command is used (e.g. if you want to add your own help information), just globally override the "HELP" command, and get it to display a text block in the help window using the helpdisplaytext command.

For example, in the game definition block:

command <help> helpdisplaytext <helpguide>

Then, write your help guide in a define text <helpguide> block. Now when a player types "HELP", the "helpguide" text block will be displayed in the help window, rather than the default Quest Quick Help guide.


How to Split Long Lines

You may find that, when writing a game, some lines won't fit nicely on the screen in your text editor - long descriptions for example. The easy way around this is to split the line, and this is done by adding an underscore character "_" to the end of a line. Quest will then process the following line as if it followed directly on from the end of the split line.

Here's a mostly-pointless example:

define object <cheese>
    properties <smell = intense; _
        type = brie; _
        price = 4>
end define

The only lines you shouldn't split are any define and end define lines.

Note that when lines are split, the continued line has all leading spaces and tabs chopped off, so if you want a space between the characters of the chopped lines, put the spaces before the underscore. For example:

look <It's a bright_
    sunny day.>

will print the description "It's a brightsunny day", which is not particularly pleasing piece of prose. The correct way is to use:

look <It's a bright _
    sunny day.>

In the examples above, I've indented the continued lines. This is only to enhance readability; it is clear that the line is not the start of a new one, only a continuation of the previous line. It is not necessary to indent lines in this way - Quest will treat the above example and

look <It's a bright _
sunny day.>

in exactly the same way.


Notes for Users of Previous Versions

These are summaries of new features that you should take note of for Quest versions 3.0 and later. For a full list with full details of changes in every version of Quest, read VERSIONS.TXT. Most new features are only applicable if you use the correct version number in your asl-version tag. To take advantage of all the latest features, use asl-version <311>.

There are no changes to ASL in Quest 3.12, so the asl-version used is 311.

What's New in Quest 3.11
What's New in Quest 3.1
What's New in Quest 3.1 Beta
What's New in Quest 3.0

What's New in Quest 3.11

  • Implemented #quest.lastobject#.
  • The exec command can now use "real" object names.
  • Any startscript specified by a library will now be executed before the calling ASL file's startscript, if both the game and the library are using ASL version 311 or later.
  • Libraries can now !include other libraries.
  • You can now read the following object tags in the same way as you read object properties: prefix, suffix, detail, gender, article, displaytype, look, examine.
  • If there is no script specified for a "place" tag in a room, Quest will automatically use the specified room's alias as the name for the exit, if it exists.
  • Libraries can now add to the "default" and "defaultroom" types by using "!addto type <default>" and "!addto type <defaultroom>"

What's New in Quest 3.1

Please also read What's New in Quest 3.1 Beta (below) if you are upgrading from Quest 3.0x.

  • There is an easier way to refer to the displayed name of an object (i.e. its alias, if it has one, or otherwise its name as it appears in code), using the #@...# form. See the updated How To Add Your Own Commands to a Game for full details in the "Two ways of referring to a string variable" section.
  • When a description tag is specified, the current room's look description is now not printed automatically. You can specify where the look description should be printed by printing the contents of the new quest.lookdesc string variable somewhere in the description script. See How To Customise Room Descriptions for an example.
  • Apostrophes in a define synonyms block are now dealt with more intelligently.
  • Added type script command.

What's New in Quest 3.1 Beta

  • There is a much easier way of reading properties.
  • There is easier disambiguation in custom commands, using the #@...# form for string variables which contain object names - see How To Add Your Own Commands to a Game. It is recommended that you always use the #@...# form when the string variable in your command tag refers to an object.
  • You can specify alternative names for an object in the object's definition block, using the alt tag rather than using synonyms.
  • The Quest parser now supports pronouns - "it", "them", "him" etc. These will be automatically handled by your custom commands, if you use the #@...# form for string variables!
  • Added MOD support - playmod.
  • Added loop support to playwav, playmidi.
  • The game definition block and room definition blocks can now include properties, action and type tags, which can be used and accessed in the same way as for object properties etc. tags.
  • You can now change foreground and background colours.
  • New commands: clone, shellexe.
  • The "badlook" error is now obsolete - when players type "LOOK OBJECT", it will be evaluated in the same way as "LOOK AT OBJECT".
  • The "badexamine" error is now the error that is printed when the player uses the "EXAMINE" command in an unrecognised way (e.g. by typing it on its own); if the subject of "examine" is unrecognised, the "badthing" error is now printed instead (as is the case for all other commands).

What's New in Quest 3.0

Quest 3.x is a major upgrade to Quest 2.x, and the way games are coded has changed in a number of significant areas. These notes will tell you what the most important changes are from a programming perspective - it is not a comprehensive list of changes by far. For a full list of new features, read VERSIONS.TXT. I also recommend you at least skim through all of the current version of the documentation, as full details on the syntaxes of new commands, and the possible new syntaxes of old commands, is contained elsewhere in the Quest Documentation.

Quest 3.x is fully backwards-compatible with Quest 2.x, so all your old games should continue to work. However, due to the nature of the differences between ASL2 (used in Quest 2.x) and ASL3 (used in Quest 3.x), "upgrading" ASL2 code to ASL3 is not something I recommend. Simply changing your asl-version tag will not work!

If you used QDK 1.x please also see the notes for users of QDK 1.x.

Combined Item/Object/Character Model

The whole nasty and confusing business of "items" being separate from "objects" has been done away with in Quest 3.x - all objects are now objects. Simple! This means there is no longer any need for items and startitems lines in your game definition block. Everything works by moving objects - so now, when the player picks up an object, that object is now moved to the player's inventory, rather than the old model which involved hiding that object and adding an equivalent item to the inventory.

This means that a typical object's take tag has become much simpler - you can in fact have a completely empty take tag, which will do the default behaviour of moving the object to the player's inventory automatically. There's no more need for a hideobject command!

Commands dealing with the taking of objects, such as the give command, have been updated to deal with the new model. The lose command behaves slightly differently however - because this is the opposite of the updated give command, which moves the object from room to inventory, the lose command now moves the object from inventory to room. If you want to emulate the old behaviour of making the object completely disappear, use the hide command instead (there's no need to use lose as well).

"Characters" are now objects as well - objects now support all the character-specific tags such as speak and gender. This means there is no need for the doubling-up of similar commands - so the old hideobject and hidechar commands are now unified as one hide command. Similarly unified are the "new" move, reveal, conceal and show commands.

The new displaytype tag allows animate objects to be of type "Character" in the "Places and Objects" list, rather than the default "Object" which would not make too much sense in the case of things which can talk, for example.

If you want the player to start a game with objects in his or her inventory, whereas before you would have used a startitems tag, you must now have all objects the player starts the game with in an "inventory" room. You can do this using a "define room <inventory>" block, or you can move objects to the "inventory" room in your startscript.

Object and Room Names

All objects and all rooms must now have completely unique names - you can no longer have two objects called "book", and also if you have an object called "car", you can't have a room called "car" defined as well. Objects now support an alias tag, so you can use this if you need to have two or more objects or rooms called the same thing.

Status Variables

Collectables are no longer supported in ASL3. They have been entirely replaced by the new status variables, which can be used in exactly the same way as string and numeric variables. For details, see the Status Variables documentation.

Other things

  • setstring and setvar will still function in ASL3, but it is recommended you use set string and set numeric to declare variables, and then just set to change their values.
  • Function parameters are now accessible using the $numberparameters$ and $parameter(...)$ functions rather than using string variables. See Parameter Functions for details.
  • Functions no longer have to use return on a separate line - the return command can now be inside an if statement, for example.
  • Because the show command is now the unified version of the old showobject and showchar commands, the command to display pictures (which was show in ASL2) is now picture.
  • Non-script tags, such as look <description>, should no longer contain variables. Use script versions such as look msg <description> instead, or, in the case of things such as aliases, change object properties rather than use string variables.
  • You can now use a prefix in an out tag.
  • When splitting long lines, you can now use single underscores "_" rather than double underscores "__".
  • If you need spaces at the beginning or the end of a string when using set string, surround the whole string in square brackets e.g. set string <myspaces; [  ]> is a string consisting of two space characters.
  • The defaulttake error in ASL2 is equivalent to the badtake error in ASL3. defaulttake is now used for the message printed for the successful taking of objects.
  • Quest is now responsive while a pause command is in effect, making this a much less horrible command to use.


QDK User's Guide

QDK 3.12 User's Guide

QDK allows you to quickly create your own adventure games, using all of Quest's advanced features, plus features of compatible Quest libraries, without coding. Create all your rooms, objects and script commands by simply pointing and clicking - then save your game, run it and compile it, all from one easy to use program!

QDK has been designed to be as intuitive to use as possible. Throughout QDK you'll find handy [image] "Infotips" giving you useful information. (If you see the [image] icon in a box, click on it for help.) For these reasons, and the fact that many of Quest's features are described in full detail in the ASL Reference, I have tried to keep this user's guide as concise as possible.

Using QDK

Game Menu

Script Menu

Text Menu

Important Notes for users of QDK 1.x (for Quest 2.x)


Using QDK

Getting Started

Main Window

Rooms

Objects

Editing Script Commands

Custom Player Commands


Getting Started

You can start using QDK by selecting it from the Quest group in your Start menu.

QDK will import any ASL file, whether created using QDK or with a text editor. When QDK saves a file originally created with a text editor, the resulting file will be slightly rearranged, although it will still function in exactly the same way as before.

Note for Quest Pro / QDK Pro users: You can compile your games directly from QDK using the QCOMPILE.EXE utility that you got with your Quest Pro upgrade. To use this feature from QDK, you'll need to tell QDK where the QCOMPILE.EXE file is. Go to the Options window by clicking Tools, then Options, and then click the Browse button to find QCOMPILE.EXE.

If you're not a Quest Pro user and would like to be able to compile your files to hide their contents from players and prevent players from editing them, upgrade to Quest Pro by clicking here.


Main Window

On the left-hand side is a list of all the rooms in the current game. When you select a room, the objects contained within it are displayed on the list on the right. If the room has an alias, it will be displayed in the status bar at the bottom of the window.

Under each pane are buttons which allow you to add, edit and delete rooms and objects. Other aspects of the game can be edited from the various menus at the top of the screen, or from the toolbar.

You can cut, copy and paste rooms in much the same way as you can cut, copy and paste files in Windows Explorer - you can select multiple objects and copy them to a different room, make complete copies of rooms, and copy rooms or objects between files. As all rooms and objects must have unique names, QDK will automatically append a number to the room or object name if necessary. An alias of the original name will be added to the object or room if no alias exists, so a copied object or room will appear the same to the player.

You can cut, copy and paste from the Edit menu, the toolbar, or by right-clicking the Rooms or Objects list.


Rooms

Rooms are places that the player can be in, and they can contain objects. They need not be rooms as such - they could equally well be the insides of vehicles, or "outside" places such as a street - basically, any location in your game needs to be set up as a room.

Selecting a room and then clicking "Edit Room", or adding a room will bring up the "Room Properties" window. This allows you to edit all aspects of the room, and specify where the exits lead to.

Details

Name: This is the name of the room as it is known to Quest and QDK, and by default it is also the name that the player will see for this room. All rooms must have different names.

Alias: If you want to present the player with a different name for this room, enter it here. If you want several rooms to be known to the player by the same name (for example, you might want multiple rooms known as "street"), you must specify different real names in the "Name" box (for example, "street1", "street2" etc.) and give them the same alias (in this case, "street").

Prefix: The prefix specifies a word to print before the room name to make things sounds more natural. For example, when the player enters a room such as "kitchen" , Quest will display "You are in kitchen" if you don't specify any prefix. To make this sound more natural, use a prefix of "the", to make Quest display "You are in the kitchen".

Description: The "Description" text is printed when the player enters the room - type some descriptive text containing information on things other than objects and exits, as these will be printed automatically (unless you specify a "Local print description script" - see below).

Description prefix: If the "Description prefix" is left blank, the default "You are in" is printed before the room name in Quest's description of the room. By typing something in this box, you can change these words - if you want the room name to be added after the description prefix, finish the text with a colon ":".

So, if you have a room called "box" and you want Quest to print "You are inside a small, dark box", use "You are inside a small, dark:" in the description prefix. Alternatively you could just type the text "You are inside a small, dark box" in the description prefix, or as another option you could use "You are inside:" in the description prefix and have "a small, dark" as your room prefix.

Exits - the "Compass" and "Go to" tabs

There are two types of exits - directional ones, which can be accessed by the player typing "OUT", "NORTH", "WEST", etc. (or by clicking the relevant button on the Quest window), and those that can be accessed using "GO TO ..."; followed by the room name.

Compass

When you drop down the list by "North to:" etc., a list of all rooms is displayed for you to choose from. You can also choose "[not accessible]" (the default), meaning the player can't go in that direction, and "[script]" (at the bottom of the list), meaning that instead of going to any particular place, a particular script is executed. By selecting "[script]", the "Edit script..." button for that direction is enabled, and clicking this allows you to specify what script is executed when a player goes in that direction.

The "Out to:" box works slightly differently - you must specify a room before you can specify a script associated with going out to that room. If a script is specified, that script will be executed instead of the player going out to that room. You can also, optionally, specify a prefix for the "Out" room - for example, if the player can go out to a room called "street", use a prefix of "the" and Quest will display "You can go out to the street" in the room description (rather than "You can go out to street", which is what would be printed if you did not specify a prefix).

Go to

The Places list shows the places that can be accessed from this room by the player typing "GO TO ...". If you don't specify any script, the player will automatically go to the room specified. If you do specify a script, that script will execute instead (you can make the script move the player to the relevant room within the script if you want).

You can optionally specify a prefix for "Go to..." exits. This prefix is displayed before the room name in the room description. For example, if you add a room "bedroom", Quest will display "You can go to bedroom". More natural English would be for Quest to display "You can go to the bedroom", so in this case you should use a prefix of "the".

Script

Player enters room script: This script is executed when the player enters the room.

Local print description script: If specified, this will completely override the Quest default description (and any "Print description script" specified on the Game Properties window) that is displayed for this room. You could simply specify to print a message here, in which case your game will have a more classical adventure game feel - but remember to mention all of the objects that the player can interact with, as Quest won't display them by default if you override the description here.

Room before turn script, Room after turn script: As for "Before turn script" and "After turn script" on the Game Properties window. If you tick "Overrides", that script will be executed instead of, rather than in addition to, the before or after turn script specified on the Game Properties window.

Misc

Edit Properties and Actions: Allows you to set up properties, actions and included types for this room. See the Object Types page for information on using this window.

Edit Custom Player Commands: Allows you to set up custom commands that apply for this room only - see Custom Commands for information.

Edit Usable Objects: Allows you to specify what objects can be used in this room, and what script is executed when these objects are used.

Edit Misc ASL Script Tags: Allows you to enter additional ASL script for this room.

Other tabs

You may see other tabs in addition to those described above, if you have included libraries in your game. Refer to the relevant library documentation for details - the name of the library that has added the tab will be displayed at the bottom of the pane for that tab.


Objects

An object can be an inanimate thing such as a book, or it could be a living person, creature, etc.

Selecting an object and then clicking "Edit Object", or adding an object will bring up the "Object Properties" window:

Description

Here you can specify various details about how this object should be referred to, and what happens when you look at, examine or speak to it.

Name: Specify the name of the object here. Each object must have a unique name.

Alias Use an alias if you want several objects to appear to have the same name, or for some other reason want the name of this object that is displayed to the player to be different to the name that is used internally in your script.

Other Names: Click this button to add other names that players might use to refer to this object.

Prefix: This is used for more natural English - a "robot" object might have a prefix of "a", "the", or even "a massive scary". This would make Quest display "You can see a robot", "You can see a massive scary robot" etc., rather than "You can see robot", which sounds horrible.

Suffix: Much like the prefix, except this is displayed after the object name in the room description. In our robot example we might use something like "which looks like he's going to squash you".

Detail: If you have more than one object with the same alias, and the player tries to take, look at, speak to etc. an object where there is ambiguity (say, there are two objects in the room with an alias of "book", and the player types "look at book"), the "Detail" is what's used in the disambiguation menu. In the case of the book, one might have a detail of "Advanced Calculus" and another "Making Amazing Games With Quest". You should use the "Detail" box, therefore, for a very brief but unique description of an object - but there's no need to do this for all objects if there's no chance of an ambiguity ever arising.

Gender: Specifies the gender of the object - usually "he", "she" or "it". The default is "it". It is used when you have not specified any "speak" script and the player tries to speak to the object - good practice is to give each of your "alive" objects a gender to avoid nastiness such as, if the player types "speak to mrs jones", Quest replying with "It says nothing", which could be rather offensive to Mrs. Jones.

Article: Usually "it" or "them". The default is "it". It is used for the default "take" message - if you have a plural object such as "cards", you should give it an article of "them", so that Quest says "You pick them up" rather than "You pick it up".

Display type: Used in the "Places and Objects" list on the Quest window for the "Type" column. You should give your "alive" objects a display type of "character" or similar, to avoid poor old Mrs. Jones from our "Gender" example being a mere "Object" as well!

"Look" script, "Examine" script: Allows you to specify what happens when the player looks at or examines the object by typing "LOOK AT" or "EXAMINE" followed by the object name, respectively. Usually your look script will print a message containing the description of the object. If you don't specify an examine script, the look script is executed when the player examines an object.

"Speak" script: Specifies what happens when the object is spoken to. Usually your speak script will print something by way of reply, or bring up a menu allowing the player to choose what they want to say.

Take

To make an object takeable, you can simply click the "Takeable" box. This will allow the player to pick the object up, and a default message will be printed. If you want something more sophisticated to happen, specify a Take script - the object won't automatically be picked up, but you can give the player the object within the script if you want.

Gain script: Specifies what happens when the player gains this object. Useful if you have script other than the "Take" script that might give the object to the player, and you want something special to happen when the player recieves the object.

Lose script: Specifies what happens when the player loses or drops this object.

Interactions

"Use" details: Here you can specify what happens when this object is used on something else, and/or what happens when something else is used on this object. You can say which objects can be used on this object, which objects this object can be used on, and more generally, what happens when anything is used on this object or this object is used on anything. You can also specify what happens when this object is used on its own.

"Give" details: As for "Use" details, but here you can specify what happens when this object is given to or received by other objects.

"Drop" details: Here you can specify if this object can be dropped everywhere or dropped nowhere, and what message to print when the player drops or tries to drop the object, respectively (if you don't specify a message to print, a default message is printed automatically). If you need more flexibility you can execute a script instead when the player tries to drop the object.

Properties and Actions: Allows you to set up properties, actions and included types for this object. See the Object Types page for information on using this window.

Initially invisible: If selected, this object will not be shown in the room description, but will be accessible to the player (for taking, speaking to, etc.).

Initially unavailable: If selected, this object will be completely inaccessible to the player until it is made accessible from script commands at some point in the game.

Edit Misc Tags: Allows you to enter additional ASL tags for this object.


Editing Script Commands

Script commands are fundamental to the way Quest works. Printing messages, playing sounds, displaying text blocks, killing the player, moving objects and much more are all done through the use of script commands. Script commands can be triggered in many circumstances, which is why many editing windows have buttons for editing script. The window that comes up whenever you click the "Edit" or "Edit script" button is the same, and this section describes how to use it.

There are two types of script commands - normal script commands, and conditional script commands. Normal script commands are executed when they are reached, whatever happens. Conditional commands are only executed if one or more conditions, such as the player having a certain object, is met.

Adding Normal Script Commands

Clicking "Add Command", or selecting a normal command and clicking "Edit", brings up the Script Command Editor.

Available commands are grouped into categories. Double-click a category (or single-click the "+" next to it), to show which commands are available in that category. When you select a command, you can enter its various parameters and read information about it in the "Command parameters / information" box, next to the command list.

Adding Conditional Commands

Clicking "Add Conditional", or selecting a conditional script command (i.e. "If ...") and clicking "Edit" brings up the Conditional Script Editor.

From here, you can specify the conditions that need to be fulfilled in the list next to "If:". If these conditions are fulfilled, the script specified by "Then:" is executed. If the conditions are not fulfilled, the "Else:" script is executed if specified; otherwise nothing happens.

To add conditions, click "Add". This will bring up the Condition Editor.

If this is the first condition in the list, the "And" and "Or" buttons are unavailable. Optionally, "NOT" can be selected so that the "Then:" action will be executed if this particular condition is NOT true.

Select the condition from the list, and enter the relevant parameters in the "Condition Parameters" box.

In many cases, you'll only want to have one condition - for example, if this is the action executed when the player types "FEED BABY", you might only want to check that the player has some "baby food" object or similar. However, there are times when you might want more than one condition - for example, you might want the baby only to be able to be fed if the player has the baby food AND the baby is hungry AND NOT ill.

When you specify script for "Then" and "Else", you will be presented with another script editor window from where you again specify ordinary script to execute, or even more conditional script - this allows you to cater for many complex situations relatively easily.


Custom Commands

There are many times when you may want the player to be able to type something in that is not handled by default in Quest - for example, you may want a player to be able to type in "READ BOOK", "EAT FISH", "DETONATE BOMB" etc. For these cases, you can set up custom commands - these can apply to single rooms, or throughout the game. You can access the Custom Command editor by clicking "Edit Custom Player Commands" in either the Game Properties window (for commands that are available throughout the game) or a Room Properties window (for commands that are available only in that room).

The Custom Command editing window

Clicking "Add", or clicking "Edit" when an existing command is selected, brings up the editing window.

In this window, enter the command that you want the player to be able to type in at the top. For a single command, just enter the command - for example "read book". If, however, you want a verb or some other more flexible command arrangement (for example, you want the player to be able to "read ..." anything, or "detonate (anything) under (anything else)", or "write (something)"), you need to use string variables. Type the command in as normal, but for sections that can "be anything", click either "Insert Text Variable" (if this "anything" can be literally anything at all), or "Insert Object Variable" (if this "anything" must be the name of an object).

For our examples:

  • to be able to "read (anything)", you might enter "read #@readthing#". This would then put anything that the player typed after "read" into the "readthing" string variable, and execute the script specified. You could then access this string variable in a script command using either "#readthing#" (to return the real object name) or "#@readthing#" (to return the object's displayed name).
  • to be able to "detonate (anything) under (anything else)", you might enter "detonate #@device# under #@thing#". So, if the player typed in "detonate bomb under car", the string variable "device" would contain "bomb" and the string variable "thing" would contain "car". You could then access these variables in other script commands by using "#device#" and "#thing#" (or, again, "#@device#" to return the displayed name of the device and "#@thing#" to return the displayed name of the thing it was detonated under).
  • to be able to "write (anything)", you might enter "write #text#". If the player typed in "write hello", the string variable "text" would contain "hello", and we could access this in other script commands by using "#text#".

You then need to specify some script to execute when this command is typed in - click "Edit" to edit the script. From the script, you may want to compare the contents of any string variables in the command with something and specify what happens as a result - in the "detonate" example above, you might want to see if the "device" variable contains something that can be used to blow things up - you might see if the player has the object referred to by "#device#" and that this object has the property "explosive" (N.B. we don't check "#@device#", as this returns the displayed name - and to check for a property, we must always use the real name of the object, as it is known to Quest, rather than the displayed name of the object, as it is known to the player). Then you might want to see if the "thing" variable contains something sensible that it can be put under, and execute some action that "explodes" this "thing" - a good example where you'd use conditional script.

Note that the commands defined here are processed from top to bottom to see if they fit what the player has typed. If a command fits what the player has typed, the relevant actions are executed and no more commands are tested. For this reason, if you want to set up commands such as "read (anything)" and "read (anything) carefully", for example, the "more detailed" one should be before the "less detailed" one - otherwise the word "carefully" will become part of the "anything" in "read (anything)".

If what the player has typed does not fit any of the user-defined commands, Quest's internal command handler comes into play and handles commands such as "GO TO..." and "LOOK AT..." in the default manner. Therefore you can override these commands simply by setting them up as user-defined commands.


Game Menu

Game Properties

Libraries

Status Variables

Timers

Object Types


Game Properties

Game properties can be changed by choosing "Properties" from the "Game" menu, or clicking the "globe" toolbar button.

Game Information

Here you can specify various details about your game, which will be printed when the player types "about" or selects "About This Game" from the "Help" menu.

Game name: Enter the name of your game here.

Start room: Select from the list which room the player will be in when the game starts. It is important to set this before trying to run your game in Quest - QDK will warn you if you forget to set a start room, and if you try to run the game in Quest with setting one, you will find that you won't be able to do much!

Game author: (Optional) Enter your name here.

Copyright (Optional) Enter any copyright information here, for example "© 2002 Silly Game Enterprises". Tip: To get the © symbol, hold down the Alt key and enter "0169" on the numeric keypad.

Extra info: (Optional) Enter any additional information you want about your game here.

Script

Start script: This script is executed when the game starts. You could use it to run an introductory sequence, or to set up any string or numeric variables your game uses, or perhaps both.

Print description script: Recommended for advanced users only. This overrides Quest's room description code for every room in the game. See How to Customise Room Descriptions for an ASL example using the relevant string variables and functions.

Before turn script: This script is executed immediately after a player types a command, before the command is processed.

After turn script: This script is executed immediately after a command has been processed.

Display

Here you can specify the default font and font size used in the game, as well as default colours for the foreground and background. Note that some users may set their Quest Options to override your font and/or colour information, so don't rely on these settings. Leave the font name empty to use the default font, and use zero for the font size to use the default font size.

If you find that it takes a while to load the Game Properties, this is due to QDK adding fonts to the fonts list. You can speed up loading the window by going to the Options window (on the main window, click the Tools menu and select Options) and turning off the "Automatically load fonts list on Game Properties window" option. If this option is turned off, you can load the fonts list if you need it by clicking the "Load List" button that will appear above the fonts list.

Global Settings

Edit Properties and Actions: Allows you to set up properties, actions and included types for the "game" object. See the Object Types page for information on using this window.

Edit Custom Player Commands: Allows you to set up custom commands that apply throughout the entire game - see Custom Commands for information.

Edit Usable Objects: Works identically to the same button on the Room Properties window, except that any items specified here will be use-able by the player from anywhere in the game.

Disable debug windows: Removes the "Debug" menu from the Quest window. This is useful for hiding internal game information from players, particularly when compiled to CAS (CAS compilation is available in Quest Pro only).

Edit Misc ASL Script Tags: Allows you to specify extra ASL tags for the "define game" block.

Other tabs

You may see other tabs in addition to those described above, if you have included libraries in your game. Refer to the relevant library documentation for details - the name of the library that has added the tab will be displayed at the bottom of the pane for that tab.


Libraries

To specify libraries to be included in the game, select "Libraries" from the "Game" menu. The Library window will show you all the libraries that are accessible to your game - those that are in the Quest directory, and those that are in the same directory as your game's ASL file. Select only those libraries that you wish to use - information about each library is displayed at the bottom of the window when it is selected.

You'll need to save your game before QDK will know which directory (other than the Quest directory) to look for library files in (you'll see at the top of the window if QDK has only looked in the Quest directory). So, if you want to use a library that's not in the Quest directory, your game needs to be saved in the same directory as the library.

Libraries can add their own interface elements - that is, additional script command categories, plus extra tabs on the Game Properties, Room Properties and/or Object Properties windows (if you're a library author, see QDK Library Interfacing for information). All libraries selected on this window will be scanned for interface elements, except for libraries which have been added manually by using the "Add" button and typing in a library filename - you'll see a message in the information pane if Quest was unable to search for interface elements in this library.


Status Variables

Status Variables are normal numeric or string variables, but their values are constantly displayed in a status area on the Quest window. Examples of variables you might set up as status variables are health and money - so the player can always check how healthy they are, how much money they have etc. by glancing to the right-hand side of the Quest window.

You can add and edit status variables by selecting "Status Variables" from the "Game" menu.

Adding a Status Variable or selecting a Status Variable and clicking "Edit" will bring up another window from where you can specify the name of the variable, its type and its initial value.

The "Display" box allows you to specify how this variable will be displayed in the status area of the Quest window. Use an "!" character where you want the value to appear, and use "*" characters to surround any characters that only appear in the plural. For example "! potato*es*" will go up "0 potatoes", "1 potato", "2 potatoes", "3 potatoes", etc., as the value of the variable increases.

Tick "Don't display when value is zero" if you don't want the variable to appear in the status area until its value is non-zero - useful for variables that are only relevant later on in a game.


Timers

Timers are used to execute script at regular intervals. You can set up timers by selecting "Timers" from the "Game" menu.

The "Interval" box lets you specify how much time elapses before this timer "fires", in seconds. If you select "Initially timer is on" for any timer, that timer will be "ticking" from the moment the game starts. If you don't select this option, you can turn the timer on using the "Turn on a timer" script command in the "Timers" category.


Object Types

Object Types allow you to specify a number of properties and actions which can be easily included in an object by including the relevant type. For example, you might want to create an "edible" type that includes an action for eating the object, plus default values for properties such as hunger satisfaction. You could then make any object edible by going to its "Properties and Actions" window and adding "edible" to the Inherited Types list.

When you add or edit an Object Type, or go to the "Properties and Actions" window for any room or object, the same window comes up. It has tabs for Properties, Actions and Types:

Properties: A property can be either boolean - that is, true or false - or it can take a value. This means that "Not" is only available if your property doesn't have a value, and your property can only take a value if "Not" is not ticked - a property of "not value = 15" doesn't make much sense.

Click "Add" to add a property and type in the property name in the "Name" box. You can then turn the property off by ticking "Not" (you might do this if, for example, an inherited type will add a boolean property that you don't want), or enter a value, if you wish.

Actions: Actions are script commands that you associate with an object, room or object type. In our "edible" example above we would add an action called "eat" to our object type. We might then add a Custom Command which would accept "eat #@object#", and then its script would run #object#'s "eat" action. This would then allow any edible object to be eaten - and if we needed a particular object to do something special when eaten, we could simply override our default "eat" action from our "edible" type by adding a different "eat" action to our particular object.

Types: Specify here any types you want to inherit. We've discussed inheriting types in objects, but you can also inherit types into other types. For example, we might make a "poison" type, which would inherit everything from "edible" but provide its own "eat" action which would kill the player or decrease the player's health.


Script Menu

Procedures and Functions

Menus

Misc ASL


Procedures and Functions

Procedures Functions

You can edit Procedures and Functions from the "Script" menu.

Procedures and Functions consist of a number of script commands. Procedures can be executed using the "Run a Procedure" script command from the "Game Control" category. Functions are like procedures, except that they return a value. You call a function by surrounding its name with "$" characters in any parameter - when this parameter is read, the function is called and its return value is placed in the parameter.

By using procedures and functions, you can create sets of commonly-used script commands that can be accessed from any point in your game.


Menus

At some point in your game you may want the player to choose something from a list of possibilities - to do this, create the menu by selecting "Menus" from the "Script" menu and add a menu. The menu name is internal to your game, and is the name you must use in the script that calls this menu.

You can specify an information prompt that will appear at the top of the menu. This is to provide instructions to the player as to what this menu is for. For example, "Choose your weapon:".

Then add choices by clicking "Add", entering the text for the choice and then specifying what script will be executed when this is selected from the menu.

When something is selected from the menu, the menu disappears, the relevant script for the selection is executed and the game continues.

To show a menu, use the "Show a menu" script command (in the "Game Control" category) at the point you want the menu to be displayed.


Misc ASL

Selecting "Misc ASL" from the "Script" menu allows you to enter additional script blocks of ASL code.


Text Menu

Text Blocks

Standard Messages

Synonyms


Text Blocks

Select "Text Blocks" from the "Text" menu to add, edit and remove text blocks.

Text blocks can be displayed at any time by using script commands. The "intro" text section is automatically displayed when the game starts; "win" when the player wins; and "lose" when the player loses. These three text sections cannot be removed.


Player Error Messages

Standard Messages

Selecting "Standard Messages" from the "Text" menu brings up the Standard Message Editor. This allows you to specify your own version of Quest's standard messages - allowing you to change the text that is printed, for example, when the player types something that Quest doesn't understand, or the player tries to look or take an object which doesn't exist.


Synonyms

When a player types in a word that has a synonym defined, that word is converted to its synonyms - this makes setting up Custom Player Commands much easier, as you can cater for commands like "read book" and "read novel" by just setting up one command for "read book". If you then set up a synonym so that the word "novel" is converted to the word "book", then when the player types "read novel", it will be automatically converted internally into "read book", and so the command for "read book" will be executed.

(Note that you can also achieve the same effect, perhaps more simply, by adding the word "novel" to the Other Names window of your "book" object on the Object Properties window.)

To add synonyms, select "Synonyms" from the "Text" menu. Here you can add and edit synonyms by specifying one or more words to convert from, and one word to convert all of these words to.

In the example above, you'd add "novel" to the "Convert..." list in the Synonyms editor, and "book" to the "to..." box.


Notes for Users of QDK 1.x

As Quest 3.x is such a major upgrade from Quest 2.x, QDK has been completely revised. This means that you cannot edit games for QDK 1.x/Quest 2.x in QDK 3.x, because ASL3 is very different to ASL2 (for more information, see the notes for Quest 2.x Game Programmers).

Combined Item/Object/Character Model

In Quest 2.x, when the player picked up an object, that object was hidden and an equivalent "item" was placed in the inventory. This has changed in Quest 3.x - objects are always objects, and when they are picked up they are simply moved to the inventory.

This means that you only need to tick the "Takeable" box of any object to let the player pick it up - no need to also define a separate item.

If you want the player to start a game with objects in his or her inventory, whereas before you would have ticked the relevant box on the Items window, you must now have all objects the player starts the game with in an "inventory" room. You could either create an "inventory" room in QDK and put the objects in there, or you could move objects in there in the Start Script.

Because characters have now become objects, there is only one list on the right-hand side of the QDK window. If you want an object to be shown in Quest's "Places and Objects" list as being a "character", type "character" in the object's "Display type" box.

Name Changes

What were called "Actions" in QDK 1.x are now called "Script Commands", to avoid confusion with the new "Actions" which can be associated with an object in Quest/QDK 3.x.

"Collectables" have been replaced by "Status Variables" in Quest 3.x, but you can edit them in much the same way in QDK.

Unique Names

All rooms and objects must now have unique names. You'll get a warning message if you try to name an object or room with a name you've already used.

If you want to have multiple objects called the same thing, you must give them all different names, but you can give them all the same alias. If there is any possibility of ambiguity (e.g. a point in the game where more than one object of the same alias is present in a room), you should give each object a distinct "Detail" - this is what shows up on the menu when the player is asked to choose which object they mean.


The Good Text Guide

Because Quest allows you to create a game quite quickly, it's tempting to just "knock something together" in a hurry and release your game early. However, if you want to create a good adventure game, there are several things you ought to bear in mind.

I won't pretend this is a comprehensive guide to creating the best game on the planet - there are other, non-authoring-system-specific guides available elsewhere on the internet for that purpose. This guide will show you briefly the Quest features you should be using to make your game experience nicer for players.

Object Names

You might not put a great deal of thought into coming up with object names - after all, they're going to be fairly obvious aren't they? However, overly descriptive object names are going to annoy your players if they have to type in commands using the whole name. Long names are all very well if players interact with your objects using only the point-and-click "Places and Objects" list, but don't forget people who prefer to use the keyboard throughout your game.

For example, say in your game you had an object called "John the Blacksmith". This might seem perfectly reasonable - but what if a player types "look at john" or "give horseshoe to john"? Quest won't find any object called "john" anywhere because what the player is referring to as "john" is actually the object "John the Blacksmith"! Clearly here a much more intuitive name for this object would be "John". We would be better off having the text "the Blacksmith" as John's suffix - now the player knows that John is a blacksmith, and they can address him as "John" as expected.

This should cover 95% of your players who will seek to address the things in your game by the most obvious names. But what if a player were now to type "look at the blacksmith" or "give horseshoe to john the blacksmith"? Quest won't find a "blacksmith" object, nor a "john the blacksmith" object! The simple way to get around this is to add these names as alt-names, by adding them to the alt tag for this object (equivalent in QDK to adding these names to the Other Names list on the Object Properties window). Quest will ignore the word the initial "the" in commands such as "LOOK AT THE BLACKSMITH", so you only need to add "blacksmith" and "john the blacksmith" to your alt tag or Other Names list.

Ways of Using Things

Suppose we have the player find an incriminating letter in our game and our player needs to burn it using some matches. We might add a "burn" command:

command <burn letter> {
    if here <letter> and got <matches> then {
        msg <You strike a match and hover it under _
            the bottom edge of the crisp sheet of _
            paper for a second. Within seconds the _
            heat causes you to drop the letter on the _
            floor, and, seconds later, only ash remains.>
        hide <letter> }
}

However, Quest allows the player to drag the object "matches" onto the object "letter", causing the command "USE MATCHES ON LETTER" to be issued. Don't forget to cater for this too! In our example, we would be better off putting the "burning" script into a procedure, and calling this procedure both from the command statement and from from an appropriate use tag, either in the "matches" or "letter" object definition blocks.

Found Other Common Annoyances?

If you've found other annoying aspects of games which occur time and time again, please drop me an email to alex@axeuk.com and I'll add them to the Good Text Guide!


Quest Pro Order Information

Upgrade to Quest Pro and you also get:

  • The Quest Compiler: Hide the source code to your games from players
  • Full version of QDK: No nag screens, and interoperability with the Quest Compiler
  • Free upgrades: Get the latest updates to version 3.x by email as soon as they are released.
  • Free technical support

Paying by Credit Card

Click here to order Quest Pro using a credit card for US $19.95, and download your upgrade today!

The credit card order facility is provided by RegNow, who operate secure servers, so your credit card details are sent encrypted. The charge on your bill will appear from "Register Now".

Paying by Cheque

To pay by cheque, run the Quest Pro Order Assistant (ORDER.EXE), answer the questions, press the Print button and then send the printed order form with your cheque to the address given by the Order Assistant.

For UK pounds sterling orders by cheque, Quest costs £9.95. For US dollars orders by cheque, Quest costs $19.95. If you're paying by cheque and want to pay in a currency other than UK£ or US$, please email enquiries@axeuk.com for price and a currency code which you can enter into the Order Assistant.

For cheque payments, delivery is by email.

For pricing for site or multiple licenses, please email enquiries@axeuk.com.

Prices are correct at time of release. For the latest pricing and ordering information please visit the Quest Pro order page at http://www.axeuk.com/quest/qreg.htm.


QCompile Manual

Run the .CAS compiler by running the QCOMPILE.EXE file in your Quest directory or selecting "QCompile" from the Quest section in your Start menu.

Using QCompile is simple - choose an input .ASL file by clicking the "Browse" button by "Input .ASL file", and then select an output file by clicking the "Browse" button by "Output .CAS file". Then click "Compile" and the .CAS file will be created in the location specified. The .CAS file can then be loaded into Quest and/or distributed as required, just like an ASL file - except that other people won't be able to see your game code, or edit it.

The .CAS compiler can also be run from a command line, using the following syntax:

        QCOMPILE [input file [; output file] ]

For example:

        QCOMPILE mygame.asl

will load the compiler with "mygame.asl" entered in the "Input .ASL file" box;

        QCOMPILE mygame.asl; mygame.cas

will load the compiler and compile "mygame.asl" to "mygame.cas", without displaying the compiler window. The progress bar and confirmation message are still displayed.

Please do not redistribute any version of QCOMPILE.EXE or any part of Quest Pro.


Contact Axe Software

If you have any comments, questions, suggestions or bug reports, please email alex@axeuk.com.

The latest version of Quest can always be found at the Axe Software Quest website, at http://www.axeuk.com/quest. New versions of Quest are also uploaded to the ftp.ifarchive.org IF archive and its mirrors, and announced on the rec.arts.int-fiction newsgroup.

If you would like to stay informed of updates to Quest, please send a blank email to axesoftware-quest-subscribe@yahoogroups.com.

If you want to hear about beta versions of Quest, please send a blank email to axesoftware-quest-beta-subscribe@yahoogroups.com.

Don't forget to check out the Axe Software forums to discuss making games with other Quest users!


File Information

Quest 3.12 - File Information

Release information

This release:

Program | Version | Build no. | Filename
Quest | 3.12 | 3.1.0154/5 | QUEST.EXE
QDK | 3.12 | 3.1.0077/8 | QDK.EXE
QCompile (Quest Pro only) | 3.11 | 3.1.0022 | QCOMPILE.EXE
Order Assistant (Quest only) | 3.1 | 3.1.0002 | ORDER.EXE

The ASL version used in this release is 3.11 (ASL 311)

Release date: 03/DEC/2002

Files

Quest Program Files

QUEST.EXE
Main Quest program
QDK.EXE
QDK, the Quest editor

Documentation

HTML documentation

QUEST.CHM
Quest Documentation (Compiled HTML Format)

Version information

VERSIONS.TXT
Details on changes in this version of Quest
VERSIONS-QDK.TXT
Details on changes in this version of QDK

Other documentation

TEMPLATE.ASL
Template ASL file

Required Files

QDK.DAT
QDK data file
QDKERR.DAT
QDK data file
QUEST.DAT
Quest data file
QEXT.DAT
Quest data file (default list of "dangerous" file types)
STANDARD.LIB
Required for some Quest 2.x games

Quest 3.x Extension Library (Version 6) by Alan Bampton

Q3EXT.QLB
Quest 3.x Extension Library (Version 6)
Q3EXT.PDF
Quest 3.x Extension Library Documentation (Adobe Acrobat Format)
Q3EXT-READ_1ST.TXT
Information for Quest 3.x Extension Library
Q3EXT.ASL
Quest 3.x Extension Library Demo

Note: The Quest 3.x Extension Library was not created by Axe Software. Please address all enquiries etc. to Alan Bampton - agbampton@aol.com.

Unregistered Version

ORDER.EXE
Quest Pro Order Assistant

Registered (Quest Pro) Version

QCOMPILE.EXE
Quest .CAS compiler

Obsolete files

Users of Quest 2.19 and earlier may delete all HTM files in the Quest directory, as these have all been replaced by QUEST.CHM. Users of Quest Pro 2.19 and earlier may delete README-QCOMPILE.TXT.

Users of Quest 2.16 and earlier may delete README-QDK.TXT.

Users of Quest 2.15 and earlier may delete REGISTER.EXE, ASL.RTF, REGISTER.RTF, README.RTF, FILEINFO.TXT.


Creating Games for Quest

ASL Reference
Full reference guide to the powerful ASL language that Quest uses.

QDK Help
Information on making games using the easy-to-use visual editor QDK.

The Good Text Guide
You can't just "knock up" an amazing game - it takes effort. This guide contains some simple advice to making your game experience nicer.